sers.ServiceStation.js 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  1. /*
  2. * sers.ServiceStation.js
  3. * Date : 2022-01-23
  4. * Version: 2.1.17-temp
  5. * author : Lith
  6. * email : serset@yeah.net
  7. */
  8. ; sers = { version: '2.1.17-temp' };
  9. /*
  10. * vit.js 扩展
  11. * author : Lith
  12. * email : serset@yeah.net
  13. */
  14. ; (function (vit) {
  15. // vit工具函数
  16. ; (function () {
  17. vit.stringToBytes = function (str) {
  18. if (!str) return [];
  19. var bytes = new Array();
  20. var len, c;
  21. len = str.length;
  22. for (var i = 0; i < len; i++) {
  23. c = str.charCodeAt(i);
  24. if (c >= 0x010000 && c <= 0x10FFFF) {
  25. bytes.push(((c >> 18) & 0x07) | 0xF0);
  26. bytes.push(((c >> 12) & 0x3F) | 0x80);
  27. bytes.push(((c >> 6) & 0x3F) | 0x80);
  28. bytes.push((c & 0x3F) | 0x80);
  29. } else if (c >= 0x000800 && c <= 0x00FFFF) {
  30. bytes.push(((c >> 12) & 0x0F) | 0xE0);
  31. bytes.push(((c >> 6) & 0x3F) | 0x80);
  32. bytes.push((c & 0x3F) | 0x80);
  33. } else if (c >= 0x000080 && c <= 0x0007FF) {
  34. bytes.push(((c >> 6) & 0x1F) | 0xC0);
  35. bytes.push((c & 0x3F) | 0x80);
  36. } else {
  37. bytes.push(c & 0xFF);
  38. }
  39. }
  40. return bytes;
  41. };
  42. vit.bytesToString = function (bytes) {
  43. if (!bytes) return null;
  44. if (typeof bytes === 'string') {
  45. return bytes;
  46. }
  47. var str = '',
  48. _arr = bytes;
  49. for (var i = 0; i < _arr.length; i++) {
  50. var one = _arr[i].toString(2),
  51. v = one.match(/^1+?(?=0)/);
  52. if (v && one.length == 8) {
  53. var bytesLength = v[0].length;
  54. var store = _arr[i].toString(2).slice(7 - bytesLength);
  55. for (var st = 1; st < bytesLength; st++) {
  56. store += _arr[st + i].toString(2).slice(2);
  57. }
  58. str += String.fromCharCode(parseInt(store, 2));
  59. i += bytesLength - 1;
  60. } else {
  61. str += String.fromCharCode(_arr[i]);
  62. }
  63. }
  64. return str;
  65. };
  66. vit.bytesToObject = function (bytes) {
  67. return eval('(' + vit.bytesToString(bytes) + ')');
  68. };
  69. vit.objectSerializeToString = function (obj) {
  70. if (obj == null || typeof (obj) == 'undefined') {
  71. return null;
  72. }
  73. var str = obj;
  74. if (typeof (str) != 'string') {
  75. str = JSON.stringify(str);
  76. }
  77. return str;
  78. };
  79. vit.objectSerializeToBytes = function (obj) {
  80. var str = vit.objectSerializeToString(obj);
  81. return vit.stringToBytes(str);
  82. };
  83. //合并连个数组
  84. vit.arrayConcat = function (a, b, count) {
  85. //a.push.apply(a, b);
  86. if (!count) count = b.length;
  87. for (var t = 0; t < count; t++) {
  88. a.push(b[t]);
  89. }
  90. return a;
  91. };
  92. vit.bytesToArrayBuffer = function (bytes) {
  93. return new Uint8Array(bytes).buffer;
  94. };
  95. vit.bytesToDataView = function (bytes) {
  96. return new DataView(vit.bytesToArrayBuffer(bytes));
  97. };
  98. vit.arrayBufferToBytes = function (arrayBuffer) {
  99. return Array.from(new Uint8Array(arrayBuffer));
  100. };
  101. vit.dataViewToBytes = function (dataView) {
  102. return vit.arrayBufferToBytes(dataView.buffer);
  103. };
  104. vit.bytesGetInt32 = function (bytes, index) {
  105. return new DataView(new Uint8Array(bytes).buffer).getInt32(index || 0, true);
  106. };
  107. vit.int32ToBytes = function (int32) {
  108. var buffer = new ArrayBuffer(4);
  109. var view = new DataView(buffer);
  110. view.setInt32(0, int32, true);
  111. return vit.dataViewToBytes(view);
  112. };
  113. vit.bytesInsertInt32 = function (bytes, index, int32) {
  114. var bytesInt32 = vit.int32ToBytes(int32);
  115. bytes.splice(index, 0, bytesInt32[0], bytesInt32[1], bytesInt32[2], bytesInt32[3]);
  116. return bytes;
  117. };
  118. // return '112233445566778899aabbccddee'
  119. vit.guid = function guid() {
  120. function S4() {
  121. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  122. }
  123. return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4());
  124. };
  125. })();
  126. //vit.logger
  127. (function (logger) {
  128. /*** 对Date的扩展,将 Date 转化为指定格式的String * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)
  129. * 可以用 1-2 个占位符 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
  130. * eg:
  131. * (newDate()).pattern("yyyy-MM-dd hh:mm:ss.S")==> 2006-07-02 08:09:04.423
  132. * (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
  133. * (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
  134. * (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
  135. * (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
  136. */
  137. Date.prototype.pattern = function (fmt) {
  138. var o = {
  139. "M+": this.getMonth() + 1, //月份
  140. "d+": this.getDate(), //日
  141. "h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
  142. "H+": this.getHours(), //小时
  143. "m+": this.getMinutes(), //分
  144. "s+": this.getSeconds(), //秒
  145. "q+": Math.floor((this.getMonth() + 3) / 3), //季度
  146. "S": this.getMilliseconds() //毫秒
  147. };
  148. var week = {
  149. "0": "/u65e5",
  150. "1": "/u4e00",
  151. "2": "/u4e8c",
  152. "3": "/u4e09",
  153. "4": "/u56db",
  154. "5": "/u4e94",
  155. "6": "/u516d"
  156. };
  157. if (/(y+)/.test(fmt)) {
  158. fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  159. }
  160. if (/(E+)/.test(fmt)) {
  161. fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[this.getDay() + ""]);
  162. }
  163. for (var k in o) {
  164. if (new RegExp("(" + k + ")").test(fmt)) {
  165. fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  166. }
  167. }
  168. return fmt;
  169. };
  170. //type: info/error
  171. //e: pass error when type is error
  172. //function(message,type,e){ }
  173. logger.onmessage;
  174. logger.error = function (e, message) {
  175. var msgBody = new Date().pattern("[mm:ss.S]") + '[error]' + (message || e.message || '');
  176. //console.log(e);
  177. //console.log(msgBody);
  178. try {
  179. if (logger.onmessage) logger.onmessage(msgBody, 'error', e);
  180. } catch (e) {
  181. }
  182. };
  183. logger.info = function (message) {
  184. var msgBody = new Date().pattern("[mm:ss.S]") + '[info]' + message;
  185. //console.log(msgBody);
  186. try {
  187. if (logger.onmessage) logger.onmessage(msgBody, 'info');
  188. } catch (e) {
  189. }
  190. };
  191. })(vit.logger = {});
  192. })('undefined' === typeof (vit) ? vit = {} : vit);
  193. /*
  194. * sers.CL.js 扩展
  195. * author : Lith
  196. * email : serset@yeah.net
  197. */
  198. ; (function (CL) {
  199. var logger = vit.logger;
  200. function PipeFrame() {
  201. this.write = function (arrayBuffer) {
  202. queueBuff.push(new Uint8Array(arrayBuffer));
  203. buffLen += arrayBuffer.byteLength;
  204. };
  205. //DataView list
  206. var queueBuff = [];
  207. var buffLen = 0;
  208. var QueueBuff_dataLenOfRemoved = 0;
  209. //return bytes
  210. function read(lenToPop) {
  211. if (buffLen < lenToPop) {
  212. return;
  213. }
  214. buffLen -= lenToPop;
  215. var dataToPop = [];
  216. var copyedIndex = 0;
  217. while (copyedIndex < lenToPop) {
  218. var leftCount = lenToPop - copyedIndex;
  219. var cur = queueBuff[0];
  220. if (QueueBuff_dataLenOfRemoved != 0) {
  221. cur = cur.subarray(QueueBuff_dataLenOfRemoved);
  222. }
  223. if (cur.length <= leftCount) {
  224. //dataToPop 数据长
  225. vit.arrayConcat(dataToPop, cur);
  226. copyedIndex += cur.length;
  227. QueueBuff_dataLenOfRemoved = 0;
  228. queueBuff.shift();
  229. }
  230. else {
  231. //queueBuff 数据长
  232. vit.arrayConcat(dataToPop, cur, leftCount);
  233. copyedIndex += leftCount;
  234. QueueBuff_dataLenOfRemoved += leftCount;
  235. }
  236. }
  237. return dataToPop;
  238. };
  239. var fileLen = -1;
  240. //return bytes
  241. this.readSersFile = function () {
  242. if (fileLen < 0) {
  243. var fileLen_bytes = read(4);
  244. if (!fileLen_bytes) {
  245. return null;
  246. }
  247. fileLen = vit.bytesGetInt32(fileLen_bytes, 0);
  248. }
  249. if (buffLen < fileLen) return null;
  250. var data = read(fileLen);
  251. fileLen = -1;
  252. return data;
  253. };
  254. };
  255. CL.DeliveryClient = function () {
  256. var self = this;
  257. self.host = "ws://127.0.0.1:4503";
  258. //function (bytes) { }
  259. self.event_onGetFrame;
  260. // function () { }
  261. self.event_onDisconnected;
  262. self.sendFrame = function (bytes) {
  263. if (!webSocket) throw new Error('连接尚未建立,无法发送数据,请先建立连接');
  264. vit.bytesInsertInt32(bytes, 0, bytes.length);
  265. var dataView = vit.bytesToDataView(bytes);
  266. webSocket.send(dataView);
  267. };
  268. var pipe = new PipeFrame();
  269. var webSocket = null;
  270. //callback: function(isConnected){ }
  271. self.connect = function (callback) {
  272. if (webSocket) throw new Error('连接尚未断开,不可再次连接');
  273. webSocket = new WebSocket(self.host);
  274. webSocket.binaryType = "arraybuffer";
  275. webSocket.onerror = function (event) {
  276. self.close();
  277. };
  278. webSocket.onclose = function () {
  279. self.close();
  280. };
  281. //成功被调用 或者超时被调用
  282. var isCalled = false;
  283. var onCall = function (isSuccess) {
  284. if (isCalled) return;
  285. isCalled = true;
  286. callback(isSuccess);
  287. };
  288. setTimeout(onCall, 10000);
  289. webSocket.onopen = function (event) {
  290. onCall(true);
  291. };
  292. webSocket.onmessage = function (event) {
  293. var arrayBuffer = event.data;
  294. pipe.write(arrayBuffer);
  295. //bytes
  296. var frame;
  297. while (frame = pipe.readSersFile()) {
  298. try {
  299. self.event_onGetFrame(frame);
  300. } catch (e) {
  301. logger.error(e);
  302. }
  303. }
  304. };
  305. };
  306. self.close = function () {
  307. if (!webSocket) throw new Error('尚未建立连接,无需断开');
  308. //(x.1) close socket
  309. try {
  310. webSocket.close();
  311. } catch (e) {
  312. logger.error(e);
  313. }
  314. webSocket = null;
  315. logger.info('[sers.CL]DeliveryClient.event_onDisconnected');
  316. //(x.2) event_onDisconnected
  317. if (self.event_onDisconnected) {
  318. try {
  319. self.event_onDisconnected();
  320. } catch (e) {
  321. logger.error(e);
  322. }
  323. }
  324. };
  325. };
  326. function RequestAdaptor() {
  327. var EFrameType = { request: 1, reply: 2, message: 3 };
  328. var ERequestType = { app: 0, heartBeat: 1 };
  329. var organizeVersion = "Sers.Mq.Socket.v1";
  330. var self = this;
  331. // requestKey -> requestCallback
  332. var organizeToDelivery_RequestMap = {};
  333. var reqKeyIndex = 100;
  334. //事件,向外部delivery发送字节流时被调用
  335. //function (bytes) { }
  336. self.event_onSendFrame;
  337. //事件,delivery向Organize发送请求时被调用
  338. //function (requestData, callback) { }
  339. //callback: function(replyData){ }
  340. self.event_onGetRequest;
  341. //请求超时时间(单位ms,默认300000)
  342. self.requestTimeoutMs = 300000;
  343. //外部调用,当外部从delivery读取到数据时调用
  344. self.deliveryToOrganize_onGetMessageFrame = function (bytes) {
  345. //deliveryToOrganize_ProcessFrame
  346. var msgType = bytes[0];
  347. var msgData = bytes.slice(2);
  348. switch (msgType) {
  349. case EFrameType.reply:
  350. var t = unpackReqRepFrame(msgData);
  351. var reqKey = t.reqKey;
  352. var replyData = t.oriData;
  353. var reqCallback = organizeToDelivery_RequestMap[reqKey];
  354. if (reqCallback) {
  355. delete organizeToDelivery_RequestMap[reqKey];
  356. reqCallback(replyData);
  357. }
  358. break;
  359. case EFrameType.request:
  360. var t = unpackReqRepFrame(msgData);
  361. var reqKey_bytes = t.reqKey_bytes;
  362. var requestData = t.oriData;
  363. var requestType = bytes[1];
  364. deliveryToOrganize_onGetRequest(requestType, reqKey_bytes, requestData);
  365. break;
  366. case EFrameType.message:
  367. //TODO
  368. break;
  369. }
  370. };
  371. function deliveryToOrganize_onGetRequest(requestType, reqKey_bytes, requestData) {
  372. switch (requestType) {
  373. case ERequestType.app:
  374. self.event_onGetRequest(requestData, function (replyData) {
  375. deliveryToOrganize_sendReply(reqKey_bytes, replyData);
  376. });
  377. return;
  378. case ERequestType.heartBeat:
  379. var version = vit.bytesToString(requestData);
  380. if (version == organizeVersion) {
  381. // send reply
  382. deliveryToOrganize_sendReply(reqKey_bytes, requestData);
  383. }
  384. else {
  385. // send reply
  386. deliveryToOrganize_sendReply(reqKey_bytes, [0]);
  387. }
  388. return;
  389. }
  390. }
  391. function deliveryToOrganize_sendReply(reqKey_bytes, replyData) {
  392. var repFrame = packageReqRepFrame(reqKey_bytes, replyData);
  393. delivery_sendFrame(EFrameType.reply, 0, repFrame);
  394. }
  395. //callback: function(replyData,isSuccess){ }
  396. self.sendRequest = function (requestData, callback, requestType) {
  397. var reqKey = reqKeyIndex++;
  398. //成功被调用 或者超时被调用
  399. var isCalled = false;
  400. var onCall = function (replyData, isSuccess) {
  401. if (isCalled) return;
  402. isCalled = true;
  403. if (!isSuccess) {
  404. delete organizeToDelivery_RequestMap[reqKey];
  405. }
  406. if (callback)
  407. callback(replyData, isSuccess);
  408. };
  409. setTimeout(onCall, self.requestTimeoutMs);
  410. organizeToDelivery_RequestMap[reqKey] = function (replyData) { onCall(replyData, true); };
  411. var reqKey_bytes = vit.int32ToBytes(reqKey);
  412. reqKey_bytes.push(0, 0, 0, 0);
  413. var reqRepFrame = packageReqRepFrame(reqKey_bytes, requestData);
  414. delivery_sendFrame(EFrameType.request, requestType || ERequestType.app, reqRepFrame);
  415. };
  416. function delivery_sendFrame(msgType, requestType, bytes) {
  417. bytes.splice(0, 0, msgType, requestType);
  418. self.event_onSendFrame(bytes);
  419. }
  420. //reqKey_bytes 8字节
  421. //返回 reqRepFrame[bytes]
  422. function packageReqRepFrame(reqKey_bytes, oriData) {
  423. return vit.arrayConcat(reqKey_bytes, oriData);
  424. }
  425. // 返回对象 {reqKey:reqKey,reqKey_bytes:reqKey_bytes, oriData:oriData}
  426. function unpackReqRepFrame(reqRepFrame) {
  427. var reqKey = vit.bytesGetInt32(reqRepFrame, 0);
  428. return { reqKey: reqKey, reqKey_bytes: reqRepFrame.slice(0, 8), oriData: reqRepFrame.slice(8) };
  429. }
  430. }
  431. //websocketHost demo: "ws://127.0.0.1:4503"
  432. CL.OrganizeClient = function (websocketHost) {
  433. var self = this;
  434. var delivery = new CL.DeliveryClient();
  435. //连接秘钥,用以验证连接安全性。服务端和客户端必须一致
  436. self.secretKey = "SersCL";
  437. //设置websocket host 地址 demo: "ws://127.0.0.1:4503"
  438. self.setHost = function (websocketHost) {
  439. delivery.host = websocketHost;
  440. };
  441. self.setHost(websocketHost);
  442. var requestAdaptor = new RequestAdaptor();
  443. //初始化requestAdaptor 和 delivery
  444. (function () {
  445. delivery.event_onGetFrame = function (bytes) {
  446. requestAdaptor.deliveryToOrganize_onGetMessageFrame(bytes);
  447. };
  448. requestAdaptor.event_onGetRequest = function (requestData, callback) {
  449. self.event_onGetRequest(requestData, callback);
  450. };
  451. requestAdaptor.event_onSendFrame = function (bytes) {
  452. delivery.sendFrame(bytes);
  453. };
  454. delivery.event_onDisconnected = function () {
  455. if (self.event_onDisconnected)
  456. self.event_onDisconnected.apply(self, arguments);
  457. };
  458. })();
  459. //function (event) { }
  460. self.event_onDisconnected = null;
  461. //function (requestData,callback) { }
  462. //callback function(replyData){}
  463. self.event_onGetRequest = null;
  464. //callback: function(replyData,isSuccess){ }
  465. self.sendRequest = function (requestData, callback) {
  466. requestAdaptor.sendRequest(requestData, callback);
  467. };
  468. //callback: function (isSuccess) { }
  469. self.connect = function (callback) {
  470. delivery.connect(function (isSuccess) {
  471. //(x.1)连接不成功
  472. if (!isSuccess)
  473. callback(false);
  474. //(x.2)进行权限校验
  475. //setTimeout(function () {
  476. self.sendRequest(vit.stringToBytes(self.secretKey), function (replyData, isSuccess) {
  477. //(x.x.1)请求不成功
  478. if (!isSuccess) {
  479. callback(false);
  480. return;
  481. }
  482. //(x.x.2)验证不成功
  483. if (vit.bytesToString(replyData) != 'true') {
  484. callback(false);
  485. return;
  486. }
  487. //(x.x.3)验证成功
  488. callback(true);
  489. });
  490. //}, 5000);
  491. });
  492. };
  493. self.stop = function () {
  494. delivery.close();
  495. };
  496. }
  497. })(sers.CL || (sers.CL = {}));
  498. /*
  499. * sers.ServiceStation.js 扩展
  500. * author : Lith
  501. * email : serset@yeah.net
  502. */
  503. ; (function (sers) {
  504. var logger = vit.logger;
  505. //ApiMessage
  506. function ApiMessage() {
  507. var self = this;
  508. //bytes
  509. var rpcContextData_OriData;
  510. //bytes
  511. var value_OriData;
  512. //return object
  513. self.getRpcData = function () {
  514. var strRpc = vit.bytesToString(rpcContextData_OriData);
  515. if (!strRpc) return {};
  516. return eval('(' + strRpc + ')');
  517. };
  518. //return bytes
  519. self.getValueBytes = function () {
  520. return value_OriData;
  521. };
  522. //return string
  523. self.getValueString = function () {
  524. var strValue = vit.bytesToString(value_OriData);
  525. return strValue;
  526. };
  527. //return object
  528. self.getValueObject = function () {
  529. return eval('(' + self.getValueString() + ')');
  530. };
  531. self.initAsApiRequestMessage = function (route, arg, httpMethod) {
  532. var rpcData = {
  533. "route": route,
  534. "caller": {
  535. "rid": vit.guid(),
  536. "callStack": [], // parentRequestGuid array
  537. "source": "Internal"
  538. },
  539. "http": {
  540. "method": httpMethod || "GET"
  541. }
  542. };
  543. rpcContextData_OriData = vit.objectSerializeToBytes(rpcData);
  544. value_OriData = vit.objectSerializeToBytes(arg);
  545. };
  546. self.package = function () {
  547. return ApiMessage.package(rpcContextData_OriData, value_OriData);
  548. };
  549. self.unpackage = function (oriData) {
  550. var files = ApiMessage.unpackage(oriData);
  551. rpcContextData_OriData = files[0];
  552. value_OriData = files[1];
  553. };
  554. };
  555. //(bytes files)
  556. //return bytes
  557. ApiMessage.package = function () {
  558. var files = arguments;
  559. var oriData = [];
  560. for (var t = 0; t < files.length; t++) {
  561. var file = files[t];
  562. vit.arrayConcat(oriData, vit.int32ToBytes(file.length));
  563. vit.arrayConcat(oriData, file);
  564. }
  565. return oriData;
  566. };
  567. //(bytes oriData)
  568. //return bytes fileArray
  569. ApiMessage.unpackage = function (oriData) {
  570. var files = [];
  571. var curIndex = 0;
  572. while (curIndex < oriData.length) {
  573. var fileLength = vit.bytesGetInt32(oriData, curIndex);
  574. var fileContent = oriData.slice(curIndex + 4, curIndex + 4 + fileLength);
  575. curIndex += 4 + fileLength;
  576. files.push(fileContent);
  577. }
  578. return files;
  579. };
  580. sers.ApiMessage = ApiMessage;
  581. //ApiClient
  582. sers.ApiClient = function (organizeClient) {
  583. //(string route, object arg, string httpMethod, function callback)
  584. //callback: function(isSuccess,replyData_bytes,replyRpcData_object)
  585. this.callApiAsync = function (route, arg, httpMethod, callback) {
  586. var apiRequestMessage = new ApiMessage();
  587. apiRequestMessage.initAsApiRequestMessage(route, arg, httpMethod);
  588. organizeClient.sendRequest(apiRequestMessage.package(), function (replyData, isSuccess) {
  589. if (!callback) return;
  590. if (!isSuccess) {
  591. callback(false);
  592. } else {
  593. var apiMessage = new ApiMessage();
  594. apiMessage.unpackage(replyData);
  595. var rpcData = apiMessage.getRpcData();
  596. var value = apiMessage.getValueBytes();
  597. callback(true, value, rpcData);
  598. }
  599. });
  600. };
  601. };
  602. //LocalApiService
  603. sers.LocalApiService = function () {
  604. var self = this;
  605. // route_httpMethod -> ApiNode
  606. // ApiNode: { apiDesc,onInvoke,onInvokeAsync } //onInvoke 和 onInvokeAsync 指定其一即可
  607. // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
  608. // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
  609. // onInvokeFinish :(replyData_bytes)=>{ }
  610. var apiNodeMap = {};
  611. //return [ ApiNode ];
  612. //ApiNode {apiDesc:apiDesc }
  613. self.getApiNodes = function () {
  614. var apiNodes = [];
  615. for (var key in apiNodeMap) {
  616. apiNodes.push({ apiDesc: apiNodeMap[key].apiDesc });
  617. }
  618. return apiNodes;
  619. };
  620. //清空已加载的apiNode
  621. self.clearApiNodes = function () {
  622. apiNodeMap = {};
  623. };
  624. // ApiNode: { apiDesc,onInvoke,onInvokeAsync } //onInvoke 和 onInvokeAsync 指定其一即可
  625. // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
  626. // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
  627. // onInvokeFinish :(replyData_bytes)=>{ }
  628. self.addApiNode = function (apiNode) {
  629. var apiKey = apiNode.apiDesc.route + '_' + apiNode.apiDesc.extendConfig.httpMethod;
  630. apiNodeMap[apiKey] = apiNode;
  631. };
  632. // apiInvoke {route: '/JsStation/api', httpMethod: 'GET', name: 'call api in js server', description: 'js作为服务站点', onInvoke,onInvokeAsync}
  633. // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
  634. // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
  635. // onInvokeFinish :(replyData_bytes)=>{ }
  636. self.addApiInvoke = function (apiInvoke) {
  637. var apiDesc = {
  638. route: apiInvoke.route,
  639. name: apiInvoke.name,
  640. description: apiInvoke.description,
  641. extendConfig: {
  642. httpMethod: apiInvoke.httpMethod
  643. }
  644. };
  645. self.addApiNode({ apiDesc, onInvoke: apiInvoke.onInvoke, onInvokeAsync: apiInvoke.onInvokeAsync });
  646. };
  647. // apiInvoke {route: '/JsStation/api', httpMethod: 'GET', name: 'call api in js server', description: 'js作为服务站点', onInvoke,onInvokeAsync}
  648. // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
  649. // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
  650. // onInvokeFinish :(replyData_bytes)=>{ }
  651. self.addApiInvokeArray = function (apiInvokeArray) {
  652. for (var apiInvoke of apiInvokeArray) {
  653. self.addApiInvoke(apiInvoke);
  654. }
  655. };
  656. //(Error e,requestData_bytes,rpcData_object,replyRpcData_object)
  657. //localApiService.onError = (e,requestData_bytes,rpcData_object,replyRpcData_object)=>{ return {success:false}; }
  658. self.onError = function (e, requestData_bytes, rpcData_object, replyRpcData_object) {
  659. logger.error(e);
  660. var reply = {
  661. success: false,
  662. error: {
  663. errorMessage: e.message,
  664. errorDetail: { name: e.name, stack: e.stack }
  665. }
  666. };
  667. return reply;
  668. };
  669. //invoke local api
  670. //apiRequestMessage:bytes
  671. //callback: (reply_bytes)=>{ }
  672. self.invokeApiAsync = (apiRequestMessage, callback)=>{
  673. //(x.1) 解析请求数据
  674. var apiMessage = new ApiMessage();
  675. apiMessage.unpackage(apiRequestMessage);
  676. var rpcData_object = apiMessage.getRpcData();
  677. var requestData_bytes = apiMessage.getValueBytes();
  678. //(x.2)解析路由获得 处理函数
  679. var route = rpcData_object.route;
  680. var httpMethod = rpcData_object.http.method;
  681. var apiKey = route + '_' + httpMethod;
  682. var apiNode = apiNodeMap[apiKey];
  683. //(x.3)进行处理获得结果数据
  684. var replyRpcData_object = {}, replyData_bytes;
  685. var onInvokeFinish = (replyData_bytes) => {
  686. //返回结果数据
  687. var apiReplyMessage_bytes = ApiMessage.package(
  688. vit.objectSerializeToBytes(replyRpcData_object),
  689. replyData_bytes
  690. );
  691. callback(apiReplyMessage_bytes);
  692. };
  693. if (apiNode) {
  694. try {
  695. if (apiNode.onInvoke) {
  696. replyData_bytes = apiNode.onInvoke(requestData_bytes, rpcData_object, replyRpcData_object);
  697. } else if (apiNode.onInvokeAsync) {
  698. apiNode.onInvokeAsync(requestData_bytes, rpcData_object, replyRpcData_object, onInvokeFinish);
  699. return;
  700. }
  701. } catch (e) {
  702. var reply = self.onError(e, requestData_bytes, rpcData_object, replyRpcData_object);
  703. replyData_bytes = vit.objectSerializeToBytes(reply);
  704. }
  705. } else {
  706. var reply = {
  707. success: false,
  708. error: {
  709. errorCode: 404,
  710. errorMessage: "Api Not Found",
  711. errorDetail: { source: 'from JsStation' }
  712. }
  713. };
  714. replyData_bytes = vit.objectSerializeToBytes(reply);
  715. }
  716. onInvokeFinish(replyData_bytes);
  717. };
  718. };
  719. //ServiceStation
  720. sers.ServiceStation = function () {
  721. var self = this;
  722. //(x.1) LocalApiService
  723. (function () {
  724. self.localApiService = new sers.LocalApiService();
  725. })();
  726. //(x.2) OrganizeClient self.org
  727. (function () {
  728. self.org = new sers.CL.OrganizeClient("ws://127.0.0.1:4503");
  729. //self.org.event_onDisconnected = function () {
  730. // logger.info('[sers.CL]org.event_onDisconnected');
  731. //};
  732. self.org.event_onGetRequest = self.localApiService.invokeApiAsync;
  733. })();
  734. //(x.3) ApiClient
  735. (function () {
  736. self.apiClient = new sers.ApiClient(self.org);
  737. })();
  738. //(x.4)
  739. self.stop = function () {
  740. logger.info('[sers.ServiceStation] try stop...');
  741. self.org.stop();
  742. logger.info('[sers.ServiceStation] stoped.');
  743. };
  744. //(x.5)
  745. self.serviceStationInfo = {
  746. serviceStationName: 'JsStation', serviceStationKey: '', stationVersion: '', info: {}
  747. };
  748. //(x.6)
  749. var deviceInfo = { deviceKey: ('' + Math.random()).substr(2) };
  750. //(x.7)
  751. //callback: function(isSuccess){}
  752. self.start = function (callback) {
  753. logger.info('[sers.CL] try connect...');
  754. self.org.connect(function (isSuccess) {
  755. if (!isSuccess) {
  756. logger.info('[sers.CL] org cannot connect to server!');
  757. if (callback) callback(false);
  758. return;
  759. }
  760. //向服务中心注册localApiService
  761. logger.info('[ServiceStation] regist serviceStation to ServiceCenter...');
  762. var apiNodes = self.localApiService.getApiNodes();
  763. var serviceStationData = {
  764. serviceStationInfo: self.serviceStationInfo,
  765. deviceInfo: deviceInfo,
  766. apiNodes: apiNodes
  767. };
  768. //(string route, object arg, string httpMethod, function callback)
  769. //callback: function(isSuccess,replyData_bytes,replyRpcData_object)
  770. self.apiClient.callApiAsync("/_sys_/serviceStation/regist", serviceStationData, 'POST', function (isSuccess, replyData_bytes, replyRpcData_object) {
  771. if (!isSuccess) {
  772. logger.info("[ServiceStation] regist - failed");
  773. if (callback) callback(false);
  774. return;
  775. }
  776. var apiRet = vit.bytesToObject(replyData_bytes);
  777. if (!apiRet.success) {
  778. logger.info("[ServiceStation] regist - failed. reply:" + vit.bytesToString(replyData_bytes));
  779. if (callback) callback(false);
  780. return;
  781. }
  782. logger.info("[ServiceStation] regist - succeed");
  783. if (callback) callback(true);
  784. });
  785. });
  786. };
  787. }
  788. })(sers);