ts-sdk

index.js 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. return new (P || (P = Promise))(function (resolve, reject) {
  4. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  5. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  6. function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
  7. step((generator = generator.apply(thisArg, _arguments || [])).next());
  8. });
  9. };
  10. var __generator = (this && this.__generator) || function (thisArg, body) {
  11. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  12. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  13. function verb(n) { return function (v) { return step([n, v]); }; }
  14. function step(op) {
  15. if (f) throw new TypeError("Generator is already executing.");
  16. while (_) try {
  17. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  18. if (y = 0, t) op = [op[0] & 2, t.value];
  19. switch (op[0]) {
  20. case 0: case 1: t = op; break;
  21. case 4: _.label++; return { value: op[1], done: false };
  22. case 5: _.label++; y = op[1]; op = [0]; continue;
  23. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  24. default:
  25. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  26. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  27. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  28. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  29. if (t[2]) _.ops.pop();
  30. _.trys.pop(); continue;
  31. }
  32. op = body.call(thisArg, _);
  33. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  34. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  35. }
  36. };
  37. exports.__esModule = true;
  38. var constant = require("./constant");
  39. var packet_1 = require("./packet");
  40. var utils_1 = require("./utils");
  41. /**
  42. * Client ws client, 单例模式, 负责维护连接
  43. */
  44. var Client = /** @class */ (function () {
  45. function Client(url, readyStateCallback) {
  46. if (!('WebSocket' in window)) {
  47. return;
  48. }
  49. this.requestHeader = '';
  50. this.maxPayload = constant.MAX_PAYLOAD;
  51. this.url = url;
  52. this.readyStateCallback = readyStateCallback;
  53. this.reconnectTimes = 0;
  54. this.reconnectLock = false;
  55. this.socket = this.connect();
  56. }
  57. // 向服务端发送ping包保持长连接
  58. Client.prototype.ping = function (param, callback) {
  59. if (param === void 0) { param = {}; }
  60. if (callback === void 0) { callback = {}; }
  61. if (typeof callback !== 'object') {
  62. throw new Error('callback must be an object');
  63. }
  64. if (this.socket.readyState !== this.socket.OPEN) {
  65. throw new Error('asyncSend: connection refuse');
  66. }
  67. var _this = this;
  68. this.addMessageListener(0, function (data) {
  69. var code = _this.getResponseProperty('code');
  70. if (typeof code !== 'undefined') {
  71. var message = _this.getResponseProperty('message');
  72. if (this.callback.onError !== null) {
  73. this.callback.onError(code, message);
  74. }
  75. }
  76. else {
  77. this.callback.onSuccess(data);
  78. }
  79. this.callback.onEnd();
  80. });
  81. var p = new packet_1.Packet();
  82. _this.send(p.pack(0, 0, _this.requestHeader, JSON.stringify(param)));
  83. };
  84. Client.prototype.send = function (data) {
  85. if (this.socket.readyState !== this.socket.OPEN) {
  86. console.error('WebSocket is already in CLOSING or CLOSED state.');
  87. return;
  88. }
  89. try {
  90. this.socket.send(data);
  91. }
  92. catch (e) {
  93. console.log('send data error', e);
  94. }
  95. };
  96. /**
  97. * asyncSend
  98. * @param {*} operator
  99. * @param {*} param
  100. * @param {*} callback 仅此次有效的callback
  101. */
  102. Client.prototype.asyncSend = function (operator, param, callback) {
  103. console.info('websocket send data', operator, this.requestHeader, param);
  104. if (typeof callback !== 'object') {
  105. throw new Error('callback must be an object');
  106. }
  107. if (this.socket.readyState !== this.socket.OPEN) {
  108. throw new Error('asyncSend: connection refuse');
  109. }
  110. if (callback.hasOwnProperty('onStart') &&
  111. typeof callback.onStart === 'function') {
  112. callback.onStart();
  113. }
  114. var _this = this;
  115. var sequence = new Date().getTime();
  116. var listener = utils_1.Utils.crc32(operator) + sequence;
  117. this.callback[listener] = function (data) {
  118. var code = _this.getResponseProperty('code');
  119. if (typeof code !== 'undefined') {
  120. var message = _this.getResponseProperty('message');
  121. if (callback.hasOwnProperty('onError') &&
  122. typeof callback.onError === 'function') {
  123. callback.onError(code, message);
  124. }
  125. }
  126. else {
  127. if (callback.hasOwnProperty('onSuccess') &&
  128. typeof callback.onSuccess === 'function') {
  129. callback.onSuccess(data);
  130. }
  131. }
  132. if (callback.hasOwnProperty('onEnd') &&
  133. typeof callback.onEnd === 'function') {
  134. callback.onEnd();
  135. }
  136. delete _this.callback[listener];
  137. };
  138. var p = new packet_1.Packet();
  139. this.send(p.pack(utils_1.Utils.crc32(operator), sequence, this.requestHeader, JSON.stringify(param)));
  140. };
  141. // 同步请求服务端数据
  142. Client.prototype.syncSend = function (operator, param, callback) {
  143. return __awaiter(this, void 0, void 0, function () {
  144. return __generator(this, function (_a) {
  145. switch (_a.label) {
  146. case 0: return [4 /*yield*/, this.asyncSend(operator, param, callback)];
  147. case 1:
  148. _a.sent();
  149. return [2 /*return*/];
  150. }
  151. });
  152. });
  153. };
  154. // 添加消息监听
  155. Client.prototype.addMessageListener = function (operator, listener) {
  156. this.callback[utils_1.Utils.crc32(operator)] = listener;
  157. };
  158. // 移除消息监听
  159. Client.prototype.removeMessageListener = function (operator) {
  160. delete this.callback[utils_1.Utils.crc32(operator)];
  161. };
  162. // 获取socket的链接状态
  163. Client.prototype.getReadyState = function () {
  164. return this.socket.readyState;
  165. };
  166. // 设置单个请求能够处理的最大字节数
  167. Client.prototype.setMaxPayload = function (maxPayload) {
  168. this.maxPayload = maxPayload;
  169. };
  170. // 设置请求属性
  171. Client.prototype.setRequestProperty = function (key, value) {
  172. var v = this.getRequestProperty(key);
  173. this.requestHeader = this.requestHeader.replace(key + '=' + v + ';', '');
  174. this.requestHeader = this.requestHeader + key + '=' + value + ';';
  175. };
  176. // 获取请求属性
  177. Client.prototype.getRequestProperty = function (key) {
  178. var values = this.requestHeader.split(';');
  179. for (var index in values) {
  180. var kv = values[index].split('=');
  181. if (kv[0] === key) {
  182. return kv[1];
  183. }
  184. }
  185. };
  186. // 设置Response属性
  187. Client.prototype.setResponseProperty = function (key, value) {
  188. var v = this.getResponseProperty(key);
  189. this.responseHeader = this.responseHeader.replace(key + '=' + v + ';', '');
  190. this.responseHeader = this.responseHeader + key + '=' + value + ';';
  191. };
  192. // 获取响应属性
  193. Client.prototype.getResponseProperty = function (key) {
  194. var values = this.responseHeader.split(';');
  195. for (var index in values) {
  196. var kv = values[index].split('=');
  197. if (kv[0] === key) {
  198. return kv[1];
  199. }
  200. }
  201. };
  202. // 创建连接
  203. Client.prototype.connect = function () {
  204. var url = this.url;
  205. var readyStateCallback = this.readyStateCallback;
  206. var ws = new WebSocket(url);
  207. var _this = this;
  208. ws.binaryType = 'blob';
  209. ws.onopen = function (ev) {
  210. console.info('websocket connected');
  211. _this.reconnectTimes = 0;
  212. if (readyStateCallback.hasOwnProperty('onopen') &&
  213. typeof readyStateCallback.onopen === 'function') {
  214. readyStateCallback.onopen(ev);
  215. }
  216. };
  217. ws.onclose = function (ev) {
  218. console.info('websocket disconnected');
  219. _this.reconnect();
  220. if (readyStateCallback.hasOwnProperty('onclose') &&
  221. typeof readyStateCallback.onclose === 'function') {
  222. readyStateCallback.onclose(ev);
  223. }
  224. };
  225. ws.onerror = function (ev) {
  226. console.info('websocket error disconnected');
  227. _this.reconnect();
  228. if (readyStateCallback.hasOwnProperty('onerror') &&
  229. typeof readyStateCallback.onerror === 'function') {
  230. readyStateCallback.onerror(ev);
  231. }
  232. };
  233. ws.onmessage = function (ev) {
  234. if (ev.data instanceof Blob) {
  235. var reader = new FileReader();
  236. reader.readAsArrayBuffer(ev.data);
  237. reader.onload = function () {
  238. try {
  239. var packet = new packet_1.Packet().unPack(this.result);
  240. var packetLength = packet.headerLength + packet.bodyLength + 20;
  241. if (packetLength > constant.MAX_PAYLOAD) {
  242. throw new Error('the packet is big than ' + constant.MAX_PAYLOAD);
  243. }
  244. var operator = Number(packet.operator) + Number(packet.sequence);
  245. if (_this.callback.hasOwnProperty(operator)) {
  246. if (packet.body === '') {
  247. packet.body = '{}';
  248. }
  249. _this.responseHeader = packet.header;
  250. _this.callback[operator](JSON.parse(packet.body));
  251. }
  252. if (operator !== 0 && packet.body !== 'null') {
  253. console.info('receive data', packet.body);
  254. }
  255. }
  256. catch (e) {
  257. console.info(e);
  258. throw new Error(e);
  259. }
  260. };
  261. }
  262. else {
  263. throw new Error('websocket unsupported data format');
  264. }
  265. };
  266. return ws;
  267. };
  268. Client.prototype.reconnect = function () {
  269. var _this_1 = this;
  270. if (!this.reconnectLock) {
  271. this.reconnectLock = true;
  272. console.info('websocket reconnect in ' + this.reconnectTimes + 's');
  273. // 尝试重连
  274. setTimeout(function () {
  275. _this_1.reconnectTimes++;
  276. _this_1.socket = _this_1.connect();
  277. _this_1.reconnectLock = false;
  278. }, this.reconnectTimes * 1000);
  279. }
  280. };
  281. return Client;
  282. }());
  283. //# sourceMappingURL=index.js.map