not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
5.7 KiB

  1. define(["sugar-web/env"], function (env) {
  2. 'use strict';
  3. var lastId = 0;
  4. var callbacks = {};
  5. var notificationCallbacks = {};
  6. var client = null;
  7. var inputStreams = [];
  8. function WebSocketClient(environment) {
  9. this.queue = [];
  10. this.socket = null;
  11. var that = this;
  12. env.getEnvironment(function (error, environment) {
  13. var port = environment.apiSocketPort;
  14. var socket = new WebSocket("ws://localhost:" + port);
  15. socket.binaryType = "arraybuffer";
  16. socket.onopen = function () {
  17. var params = [environment.activityId,
  18. environment.apiSocketKey];
  19. socket.send(JSON.stringify({
  20. "method": "authenticate",
  21. "id": "authenticate",
  22. "params": params
  23. }));
  24. while (that.queue.length > 0) {
  25. socket.send(that.queue.shift());
  26. }
  27. };
  28. socket.onmessage = function (message) {
  29. that.onMessage(message);
  30. };
  31. that.socket = socket;
  32. });
  33. }
  34. WebSocketClient.prototype.send = function (data) {
  35. if (this.socket && this.socket.readyState == WebSocket.OPEN) {
  36. this.socket.send(data);
  37. } else {
  38. this.queue.push(data);
  39. }
  40. };
  41. WebSocketClient.prototype.close = function () {
  42. this.socket.close();
  43. };
  44. var bus = {};
  45. function InputStream() {
  46. this.streamId = null;
  47. this.readCallback = null;
  48. }
  49. InputStream.prototype.open = function (callback) {
  50. var that = this;
  51. bus.sendMessage("open_stream", [], function (error, result) {
  52. that.streamId = result[0];
  53. inputStreams[that.streamId] = that;
  54. callback(error);
  55. });
  56. };
  57. InputStream.prototype.read = function (count, callback) {
  58. if (this.readCallback) {
  59. throw new Error("Read already in progress");
  60. }
  61. this.readCallback = callback;
  62. var buffer = new ArrayBuffer(8);
  63. var headerView = new Uint8Array(buffer, 0, 1);
  64. headerView[0] = this.streamId;
  65. var bodyView = new Uint32Array(buffer, 4, 1);
  66. bodyView[0] = count;
  67. bus.sendBinary(buffer);
  68. };
  69. InputStream.prototype.gotData = function (buffer) {
  70. var callback = this.readCallback;
  71. this.readCallback = null;
  72. callback(null, buffer);
  73. };
  74. InputStream.prototype.close = function (callback) {
  75. var that = this;
  76. function onStreamClosed(error, result) {
  77. if (callback) {
  78. callback(error);
  79. }
  80. delete inputStreams[that.streamId];
  81. }
  82. bus.sendMessage("close_stream", [this.streamId], onStreamClosed);
  83. };
  84. function OutputStream() {
  85. this.streamId = null;
  86. }
  87. OutputStream.prototype.open = function (callback) {
  88. var that = this;
  89. bus.sendMessage("open_stream", [], function (error, result) {
  90. that.streamId = result[0];
  91. callback(error);
  92. });
  93. };
  94. OutputStream.prototype.write = function (data) {
  95. var buffer = new ArrayBuffer(data.byteLength + 1);
  96. var bufferView = new Uint8Array(buffer);
  97. bufferView[0] = this.streamId;
  98. bufferView.set(new Uint8Array(data), 1);
  99. bus.sendBinary(buffer);
  100. };
  101. OutputStream.prototype.close = function (callback) {
  102. bus.sendMessage("close_stream", [this.streamId], callback);
  103. };
  104. bus.createInputStream = function (callback) {
  105. return new InputStream();
  106. };
  107. bus.createOutputStream = function (callback) {
  108. return new OutputStream();
  109. };
  110. bus.sendMessage = function (method, params, callback) {
  111. var message = {
  112. "method": method,
  113. "id": lastId,
  114. "params": params,
  115. "jsonrpc": "2.0"
  116. };
  117. if (callback) {
  118. callbacks[lastId] = callback;
  119. }
  120. client.send(JSON.stringify(message));
  121. lastId++;
  122. };
  123. bus.onNotification = function (method, callback) {
  124. notificationCallbacks[method] = callback;
  125. };
  126. bus.sendBinary = function (buffer, callback) {
  127. client.send(buffer);
  128. };
  129. bus.listen = function (customClient) {
  130. if (customClient) {
  131. client = customClient;
  132. } else {
  133. client = new WebSocketClient();
  134. }
  135. client.onMessage = function (message) {
  136. if (typeof message.data != "string") {
  137. var dataView = new Uint8Array(message.data);
  138. var streamId = dataView[0];
  139. if (streamId in inputStreams) {
  140. var inputStream = inputStreams[streamId];
  141. inputStream.gotData(message.data.slice(1));
  142. }
  143. return;
  144. }
  145. var parsed = JSON.parse(message.data);
  146. var responseId = parsed.id;
  147. if (parsed.method) {
  148. var notificationCallback = notificationCallbacks[parsed.method];
  149. if (notificationCallback !== undefined) {
  150. notificationCallback(parsed.params);
  151. }
  152. return;
  153. }
  154. if (responseId in callbacks) {
  155. var callback = callbacks[responseId];
  156. if (parsed.error === null) {
  157. callback(null, parsed.result);
  158. } else {
  159. callback(new Error(parsed.error), null);
  160. }
  161. delete callbacks[responseId];
  162. }
  163. };
  164. };
  165. bus.close = function () {
  166. client.close();
  167. client = null;
  168. };
  169. return bus;
  170. });