12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220 |
- /*
- * sers.ServiceStation.js
- * Date : 2022-05-18
- * Version: 2.1.18-preview902
- * author : Lith
- * email : serset@yeah.net
- */
- ; sers = { version: '2.1.18-preview902' };
- /*
- * vit.js 扩展
- * author : Lith
- * email : serset@yeah.net
- */
- ; (function (vit) {
- // vit工具函数
- ; (function () {
- vit.stringToBytes = function (str) {
- if (!str) return [];
- var bytes = new Array();
- var len, c;
- len = str.length;
- for (var i = 0; i < len; i++) {
- c = str.charCodeAt(i);
- if (c >= 0x010000 && c <= 0x10FFFF) {
- bytes.push(((c >> 18) & 0x07) | 0xF0);
- bytes.push(((c >> 12) & 0x3F) | 0x80);
- bytes.push(((c >> 6) & 0x3F) | 0x80);
- bytes.push((c & 0x3F) | 0x80);
- } else if (c >= 0x000800 && c <= 0x00FFFF) {
- bytes.push(((c >> 12) & 0x0F) | 0xE0);
- bytes.push(((c >> 6) & 0x3F) | 0x80);
- bytes.push((c & 0x3F) | 0x80);
- } else if (c >= 0x000080 && c <= 0x0007FF) {
- bytes.push(((c >> 6) & 0x1F) | 0xC0);
- bytes.push((c & 0x3F) | 0x80);
- } else {
- bytes.push(c & 0xFF);
- }
- }
- return bytes;
- };
- vit.bytesToString = function (bytes) {
- if (!bytes) return null;
- if (typeof bytes === 'string') {
- return bytes;
- }
- var str = '',
- _arr = bytes;
- for (var i = 0; i < _arr.length; i++) {
- var one = _arr[i].toString(2),
- v = one.match(/^1+?(?=0)/);
- if (v && one.length == 8) {
- var bytesLength = v[0].length;
- var store = _arr[i].toString(2).slice(7 - bytesLength);
- for (var st = 1; st < bytesLength; st++) {
- store += _arr[st + i].toString(2).slice(2);
- }
- str += String.fromCharCode(parseInt(store, 2));
- i += bytesLength - 1;
- } else {
- str += String.fromCharCode(_arr[i]);
- }
- }
- return str;
- };
- vit.bytesToObject = function (bytes) {
- return eval('(' + vit.bytesToString(bytes) + ')');
- };
- vit.objectSerializeToString = function (obj) {
- if (obj == null || typeof (obj) == 'undefined') {
- return null;
- }
- var str = obj;
- if (typeof (str) != 'string') {
- str = JSON.stringify(str);
- }
- return str;
- };
- vit.objectSerializeToBytes = function (obj) {
- var str = vit.objectSerializeToString(obj);
- return vit.stringToBytes(str);
- };
- //合并连个数组
- vit.arrayConcat = function (a, b, count) {
- //a.push.apply(a, b);
- if (!count) count = b.length;
- for (var t = 0; t < count; t++) {
- a.push(b[t]);
- }
- return a;
- };
- vit.bytesToArrayBuffer = function (bytes) {
- return new Uint8Array(bytes).buffer;
- };
- vit.bytesToDataView = function (bytes) {
- return new DataView(vit.bytesToArrayBuffer(bytes));
- };
- vit.arrayBufferToBytes = function (arrayBuffer) {
- return Array.from(new Uint8Array(arrayBuffer));
- };
- vit.dataViewToBytes = function (dataView) {
- return vit.arrayBufferToBytes(dataView.buffer);
- };
- vit.bytesGetInt32 = function (bytes, index) {
- return new DataView(new Uint8Array(bytes).buffer).getInt32(index || 0, true);
- };
- vit.int32ToBytes = function (int32) {
- var buffer = new ArrayBuffer(4);
- var view = new DataView(buffer);
- view.setInt32(0, int32, true);
- return vit.dataViewToBytes(view);
- };
- vit.bytesInsertInt32 = function (bytes, index, int32) {
- var bytesInt32 = vit.int32ToBytes(int32);
- bytes.splice(index, 0, bytesInt32[0], bytesInt32[1], bytesInt32[2], bytesInt32[3]);
- return bytes;
- };
- // return '112233445566778899aabbccddee'
- vit.guid = function guid() {
- function S4() {
- return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
- }
- return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4());
- };
- })();
- //vit.logger
- (function (logger) {
- /*** 对Date的扩展,将 Date 转化为指定格式的String * 月(M)、日(d)、12小时(h)、24小时(H)、分(m)、秒(s)、周(E)、季度(q)
- * 可以用 1-2 个占位符 * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
- * eg:
- * (newDate()).pattern("yyyy-MM-dd hh:mm:ss.S")==> 2006-07-02 08:09:04.423
- * (new Date()).pattern("yyyy-MM-dd E HH:mm:ss") ==> 2009-03-10 二 20:09:04
- * (new Date()).pattern("yyyy-MM-dd EE hh:mm:ss") ==> 2009-03-10 周二 08:09:04
- * (new Date()).pattern("yyyy-MM-dd EEE hh:mm:ss") ==> 2009-03-10 星期二 08:09:04
- * (new Date()).pattern("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
- */
- Date.prototype.pattern = function (fmt) {
- var o = {
- "M+": this.getMonth() + 1, //月份
- "d+": this.getDate(), //日
- "h+": this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
- "H+": this.getHours(), //小时
- "m+": this.getMinutes(), //分
- "s+": this.getSeconds(), //秒
- "q+": Math.floor((this.getMonth() + 3) / 3), //季度
- "S": this.getMilliseconds() //毫秒
- };
- var week = {
- "0": "/u65e5",
- "1": "/u4e00",
- "2": "/u4e8c",
- "3": "/u4e09",
- "4": "/u56db",
- "5": "/u4e94",
- "6": "/u516d"
- };
- if (/(y+)/.test(fmt)) {
- fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
- }
- if (/(E+)/.test(fmt)) {
- fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[this.getDay() + ""]);
- }
- for (var k in o) {
- if (new RegExp("(" + k + ")").test(fmt)) {
- fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
- }
- }
- return fmt;
- };
- //type: info/error
- //e: pass error when type is error
- //function(message,type,e){ }
- logger.onmessage;
- logger.error = function (e, message) {
- var msgBody = new Date().pattern("[mm:ss.S]") + '[error]' + (message || e.message || '');
- //console.log(e);
- //console.log(msgBody);
- try {
- if (logger.onmessage) logger.onmessage(msgBody, 'error', e);
- } catch (e) {
- }
- };
- logger.info = function (message) {
- var msgBody = new Date().pattern("[mm:ss.S]") + '[info]' + message;
- //console.log(msgBody);
- try {
- if (logger.onmessage) logger.onmessage(msgBody, 'info');
- } catch (e) {
- }
- };
- })(vit.logger = {});
- })('undefined' === typeof (vit) ? vit = {} : vit);
- /*
- * sers.CL.js 扩展
- * PipeFrame CL.DeliveryClient RequestAdaptor CL.OrganizeClient
- * author : Lith
- * email : serset@yeah.net
- */
- ; (function (CL) {
- var logger = vit.logger;
- function PipeFrame() {
- this.write = function (arrayBuffer) {
- queueBuff.push(new Uint8Array(arrayBuffer));
- buffLen += arrayBuffer.byteLength;
- };
- //DataView list
- var queueBuff = [];
- var buffLen = 0;
- var QueueBuff_dataLenOfRemoved = 0;
- //return bytes
- function read(lenToPop) {
- if (buffLen < lenToPop) {
- return;
- }
- buffLen -= lenToPop;
- var dataToPop = [];
- var copyedIndex = 0;
- while (copyedIndex < lenToPop) {
- var leftCount = lenToPop - copyedIndex;
- var cur = queueBuff[0];
- if (QueueBuff_dataLenOfRemoved != 0) {
- cur = cur.subarray(QueueBuff_dataLenOfRemoved);
- }
- if (cur.length <= leftCount) {
- //dataToPop 数据长
- vit.arrayConcat(dataToPop, cur);
- copyedIndex += cur.length;
- QueueBuff_dataLenOfRemoved = 0;
- queueBuff.shift();
- }
- else {
- //queueBuff 数据长
- vit.arrayConcat(dataToPop, cur, leftCount);
- copyedIndex += leftCount;
- QueueBuff_dataLenOfRemoved += leftCount;
- }
- }
- return dataToPop;
- };
- var fileLen = -1;
- //return bytes
- this.readSersFile = function () {
- if (fileLen < 0) {
- var fileLen_bytes = read(4);
- if (!fileLen_bytes) {
- return null;
- }
- fileLen = vit.bytesGetInt32(fileLen_bytes, 0);
- }
- if (buffLen < fileLen) return null;
- var data = read(fileLen);
- fileLen = -1;
- return data;
- };
- };
- CL.DeliveryClient = function () {
- var self = this;
- self.host = "ws://127.0.0.1:4503";
- //function (bytes) { }
- self.event_onGetFrame;
- // function () { }
- self.event_onDisconnected;
- self.sendFrame = function (bytes) {
- if (!webSocket) throw new Error('连接尚未建立,无法发送数据,请先建立连接');
- vit.bytesInsertInt32(bytes, 0, bytes.length);
- var dataView = vit.bytesToDataView(bytes);
- webSocket.send(dataView);
- };
- var pipe = new PipeFrame();
- var webSocket = null;
- //callback: function(success){ }
- self.connect = function (callback) {
- if (webSocket) throw new Error('连接尚未断开,不可再次连接');
- webSocket = new WebSocket(self.host);
- webSocket.binaryType = "arraybuffer";
- webSocket.onerror = function (event) {
- self.close();
- };
- webSocket.onclose = function () {
- self.close();
- };
- //成功被调用 或者超时被调用
- var isCalled = false;
- var onCall = function (success) {
- if (isCalled) return;
- isCalled = true;
- callback(success);
- };
- setTimeout(onCall, 10000);
- webSocket.onopen = function (event) {
- onCall(true);
- };
- webSocket.onmessage = function (event) {
- var arrayBuffer = event.data;
- pipe.write(arrayBuffer);
- //bytes
- var frame;
- while (frame = pipe.readSersFile()) {
- try {
- self.event_onGetFrame(frame);
- } catch (e) {
- logger.error(e);
- }
- }
- };
- };
- self.close = function () {
- if (!webSocket) throw new Error('尚未建立连接,无需断开');
- //(x.1) close socket
- try {
- webSocket.close();
- } catch (e) {
- logger.error(e);
- }
- webSocket = null;
- logger.info('[sers.CL]DeliveryClient.event_onDisconnected');
- //(x.2) event_onDisconnected
- if (self.event_onDisconnected) {
- try {
- self.event_onDisconnected();
- } catch (e) {
- logger.error(e);
- }
- }
- };
- };
- function RequestAdaptor() {
- var EFrameType = { request: 1, reply: 2, message: 3 };
- var ERequestType = { app: 0, heartBeat: 1 };
- var organizeVersion = "Sers.Mq.Socket.v1";
- var self = this;
- // requestKey -> requestCallback
- var organizeToDelivery_RequestMap = {};
- var reqKeyIndex = 100;
- //事件,向外部delivery发送字节流时被调用
- //function (bytes) { }
- self.event_onSendFrame;
- //事件,delivery向Organize发送请求时被调用
- //function (apiRequestMessage_bytes, callback) { }
- // callback: function(apiReplyMessage_bytes){ }
- self.event_onGetRequest;
- //事件,delivery向Organize发送请求时被调用
- //function (bytes) { }
- self.event_onGetMessage;
- //请求超时时间(单位ms,默认300000)
- self.requestTimeoutMs = 300000;
- //外部调用,当外部从delivery读取到数据时调用
- self.deliveryToOrganize_onGetMessageFrame = function (bytes) {
- //deliveryToOrganize_ProcessFrame
- var msgType = bytes[0];
- var msgData = bytes.slice(2);
- switch (msgType) {
- case EFrameType.reply:
- var t = unpackReqRepFrame(msgData);
- var reqKey = t.reqKey;
- var replyData = t.oriData;
- var reqCallback = organizeToDelivery_RequestMap[reqKey];
- if (reqCallback) {
- delete organizeToDelivery_RequestMap[reqKey];
- reqCallback(replyData);
- }
- break;
- case EFrameType.request:
- var t = unpackReqRepFrame(msgData);
- var reqKey_bytes = t.reqKey_bytes;
- var requestData = t.oriData;
- var requestType = bytes[1];
- deliveryToOrganize_onGetRequest(requestType, reqKey_bytes, requestData);
- break;
- case EFrameType.message:
- self.event_onGetMessage(msgData);
- break;
- }
- };
- function deliveryToOrganize_onGetRequest(requestType, reqKey_bytes, requestData) {
- switch (requestType) {
- case ERequestType.app:
- self.event_onGetRequest(requestData, function (apiReplyMessage_bytes) {
- deliveryToOrganize_sendReply(reqKey_bytes, apiReplyMessage_bytes);
- });
- return;
- case ERequestType.heartBeat:
- var version = vit.bytesToString(requestData);
- if (version == organizeVersion) {
- // send reply
- deliveryToOrganize_sendReply(reqKey_bytes, requestData);
- }
- else {
- // send reply
- deliveryToOrganize_sendReply(reqKey_bytes, [0]);
- }
- return;
- }
- }
- function deliveryToOrganize_sendReply(reqKey_bytes, replyData) {
- var repFrame = packageReqRepFrame(reqKey_bytes, replyData);
- delivery_sendFrame(EFrameType.reply, 0, repFrame);
- }
- //callback: ({success,replyData})=>{ }
- self.sendRequest = function (requestType, requestData, callback) {
- var reqKey = reqKeyIndex++;
- //成功被调用 或者超时被调用
- var isCalled = false;
- var onRequestFinish = function (success, replyData) {
- if (isCalled) return;
- isCalled = true;
- //if (!success)
- delete organizeToDelivery_RequestMap[reqKey];
- if (callback)
- callback({ success: success, replyData: replyData });
- };
- setTimeout(onRequestFinish, self.requestTimeoutMs);
- organizeToDelivery_RequestMap[reqKey] = function (replyData) { onRequestFinish(true, replyData); };
- var reqKey_bytes = vit.int32ToBytes(reqKey);
- reqKey_bytes.push(0, 0, 0, 0);
- var reqRepFrame = packageReqRepFrame(reqKey_bytes, requestData);
- delivery_sendFrame(EFrameType.request, requestType || ERequestType.app, reqRepFrame);
- };
- self.sendMessage = function (message_bytes) {
- delivery_sendFrame(EFrameType.message, 0, message_bytes);
- };
- function delivery_sendFrame(msgType, requestType, bytes) {
- bytes.splice(0, 0, msgType, requestType);
- self.event_onSendFrame(bytes);
- }
- //reqKey_bytes 8字节
- //返回 reqRepFrame[bytes]
- function packageReqRepFrame(reqKey_bytes, oriData) {
- return vit.arrayConcat(reqKey_bytes, oriData);
- }
- // 返回对象 {reqKey:reqKey,reqKey_bytes:reqKey_bytes, oriData:oriData}
- function unpackReqRepFrame(reqRepFrame) {
- var reqKey = vit.bytesGetInt32(reqRepFrame, 0);
- return { reqKey: reqKey, reqKey_bytes: reqRepFrame.slice(0, 8), oriData: reqRepFrame.slice(8) };
- }
- }
- //websocketHost demo: "ws://127.0.0.1:4503"
- CL.OrganizeClient = function (websocketHost) {
- var self = this;
- var delivery = new CL.DeliveryClient();
- //连接秘钥,用以验证连接安全性。服务端和客户端必须一致
- self.secretKey = "SersCL";
- //设置websocket host 地址 demo: "ws://127.0.0.1:4503"
- self.setHost = function (websocketHost) {
- delivery.host = websocketHost;
- };
- self.setHost(websocketHost);
- var requestAdaptor = new RequestAdaptor();
- //初始化requestAdaptor 和 delivery
- (function () {
- delivery.event_onGetFrame = function (bytes) {
- requestAdaptor.deliveryToOrganize_onGetMessageFrame(bytes);
- };
- requestAdaptor.event_onGetRequest = function (apiRequestMessage_bytes, callback) {
- self.event_onGetRequest(apiRequestMessage_bytes, callback);
- };
- requestAdaptor.event_onGetMessage = function (bytes) {
- self.event_onGetMessage(bytes);
- };
- requestAdaptor.event_onSendFrame = function (bytes) {
- delivery.sendFrame(bytes);
- };
- delivery.event_onDisconnected = function () {
- if (self.event_onDisconnected)
- self.event_onDisconnected.apply(self, arguments);
- };
- })();
- //function (event) { }
- self.event_onDisconnected = null;
- //function (apiRequestMessage_bytes,callback) { }
- // callback function(apiReplyMessage_bytes){}
- self.event_onGetRequest = null;
- //function (bytes) { }
- self.event_onGetMessage = null;
- //callback: ({success,replyData})=>{ }
- self.sendRequest = function (requestData, callback) {
- requestAdaptor.sendRequest(null, requestData, callback);
- };
- self.sendMessage = function (message_bytes) {
- requestAdaptor.sendMessage(message_bytes);
- };
- //callback: function (success) { }
- self.connect = function (callback) {
- delivery.connect(function (success) {
- //(x.1)连接不成功
- if (!success)
- callback(false);
- //(x.2)进行权限校验
- //setTimeout(function () {
- self.sendRequest(vit.stringToBytes(self.secretKey), function (args) {
- let success = args.success, replyData = args.replyData;
- //(x.x.1)请求不成功
- if (!success) {
- callback(false);
- return;
- }
- //(x.x.2)验证不成功
- if (vit.bytesToString(replyData) != 'true') {
- callback(false);
- return;
- }
- //(x.x.3)验证成功
- callback(true);
- });
- //}, 5000);
- });
- };
- self.stop = function () {
- delivery.close();
- };
- }
- })(sers.CL || (sers.CL = {}));
- /*
- * sers.ServiceStation.js 扩展
- * sers.ApiMessage sers.ApiClient sers.MessageClient sers.LocalApiService sers.ServiceStation
- * author : Lith
- * email : serset@yeah.net
- */
- ; (function (sers) {
- var logger = vit.logger;
- //ApiMessage
- function ApiMessage() {
- var self = this;
- //bytes
- var rpcContextData_OriData;
- //bytes
- var value_OriData;
- //return object
- self.getRpcData = function () {
- var strRpc = vit.bytesToString(rpcContextData_OriData);
- if (!strRpc) return {};
- return eval('(' + strRpc + ')');
- };
- //return bytes
- self.getValueBytes = function () {
- return value_OriData;
- };
- //return string
- self.getValueString = function () {
- var strValue = vit.bytesToString(value_OriData);
- return strValue;
- };
- //return object
- self.getValueObject = function () {
- return eval('(' + self.getValueString() + ')');
- };
- self.initAsApiRequestMessage = function (route, arg, httpMethod) {
- var rpcData = {
- "route": route,
- "caller": {
- "rid": vit.guid(),
- "callStack": [], // parentRequestGuid array
- "source": "Internal"
- },
- "http": {
- "method": httpMethod || "GET"
- }
- };
- rpcContextData_OriData = vit.objectSerializeToBytes(rpcData);
- value_OriData = vit.objectSerializeToBytes(arg);
- };
- self.package = function () {
- return ApiMessage.package(rpcContextData_OriData, value_OriData);
- };
- self.unpackage = function (oriData) {
- var files = ApiMessage.unpackage(oriData);
- rpcContextData_OriData = files[0];
- value_OriData = files[1];
- };
- };
- //arg files(bytes[])
- //return bytes
- ApiMessage.package = function () {
- var files = arguments;
- var oriData = [];
- for (var t = 0; t < files.length; t++) {
- var file = files[t];
- //if (file instanceof ArrayBuffer) {
- // file = vit.arrayBufferToBytes(file);
- //}
- vit.arrayConcat(oriData, vit.int32ToBytes(file.length));
- vit.arrayConcat(oriData, file);
- }
- return oriData;
- };
- //arg oriData(bytes)
- //return bytes[] file[]
- ApiMessage.unpackage = function (oriData) {
- var files = [];
- var curIndex = 0;
- while (curIndex < oriData.length) {
- var fileLength = vit.bytesGetInt32(oriData, curIndex);
- var fileContent = oriData.slice(curIndex + 4, curIndex + 4 + fileLength);
- curIndex += 4 + fileLength;
- files.push(fileContent);
- }
- return files;
- };
- sers.ApiMessage = ApiMessage;
- //ApiClient
- sers.ApiClient = function (organizeClient) {
- //(string route, object arg, string httpMethod, function callback)
- // callback: function({success,replyData_bytes,replyRpcData_object})
- this.callApiAsync = function (route, arg, httpMethod, callback) {
- var apiRequestMessage = new ApiMessage();
- apiRequestMessage.initAsApiRequestMessage(route, arg, httpMethod);
- organizeClient.sendRequest(apiRequestMessage.package(), function (args) {
- let success = args.success, replyData = args.replyData;
- if (!callback) return;
- if (!success) {
- callback({ success: false });
- } else {
- var apiMessage = new ApiMessage();
- apiMessage.unpackage(replyData);
- var value = apiMessage.getValueBytes();
- var replyRpcData = apiMessage.getRpcData();
- callback({ success: true, replyData_bytes: value, replyRpcData_object: replyRpcData });
- }
- });
- };
- };
- //MessageClient
- sers.MessageClient = function (organizeClient) {
- let EFrameType = {
- /// <summary>
- /// publish, msgTitle, msgData
- /// </summary>
- publish: 0,
- /// <summary>
- /// subscribe, msgTitle
- /// </summary>
- subscribe: 1,
- /// <summary>
- /// unSubscribe, msgTitle
- /// </summary>
- unSubscribe: 2,
- /// <summary>
- /// message, msgTitle, msgData
- /// </summary>
- message: 3
- };
- function sendFrame(frame) {
- organizeClient.sendMessage(frame);
- }
- this.onGetMessage = (messageData) => {
- let frame = ApiMessage.unpackage(messageData);
- let msgType = frame[0][0];
- switch (msgType) {
- case EFrameType.message:
- let msgTitle = vit.bytesToString(frame[1]);
- let msgData = frame[2];
- this.message_Consumer(msgTitle, msgData);
- break;
- }
- };
- // (msgTitle,msgData)=>void
- this.message_Consumer;
- this.message_Publish = function (msgTitle, msgData) {
- //EFrameType.publish, msgTitle, msgData
- let frame = ApiMessage.package(
- [EFrameType.publish],
- vit.stringToBytes(msgTitle),
- msgData);
- sendFrame(frame);
- };
- this.message_Subscribe = function (msgTitle) {
- //EFrameType.subscribe, msgTitle
- let frame = ApiMessage.package(
- [EFrameType.subscribe],
- vit.stringToBytes(msgTitle)
- );
- sendFrame(frame);
- };
- this.message_UnSubscribe = function (msgTitle) {
- //EFrameType.unSubscribe, msgTitle
- let frame = ApiMessage.package(
- [EFrameType.unSubscribe],
- vit.stringToBytes(msgTitle)
- );
- sendFrame(frame);
- };
- };
- //SubscriberManage
- sers.SubscriberManage = function (messageClient) {
- this.createSubscribe = (msgTitle, onGetMessage) => {
- return new sers.MessageSubscriber(this, msgTitle, onGetMessage);
- };
- //消息订阅者 msgTitle -> Subscriber[]
- let subscriberMap = {};
- // subscriber:MessageSubscriber
- this.message_Subscribe = function (subscriber) {
- let subscriberList = subscriberMap[subscriber.msgTitle];
- if (!subscriberList) {
- subscriberList = subscriberMap[subscriber.msgTitle] = [];
- messageClient.message_Subscribe(subscriber.msgTitle);
- }
- subscriberList.push(subscriber);
- };
- this.message_UnSubscribe = function (subscriber) {
- let subscriberList = subscriberMap[subscriber.msgTitle];
- if (!subscriberList) {
- return false;
- }
- subscriberList = subscriberList.filter(m => m != subscriber);
- if (subscriberList.length == 0) {
- delete subscriberMap[subscriber.msgTitle];
- messageClient.message_UnSubscribe(subscriber.msgTitle);
- }
- };
- this.message_Publish = function (msgTitle, msgData) {
- messageClient.message_Publish(msgTitle, msgData);
- };
- messageClient.message_Consumer = (msgTitle, msgData) => {
- let subscriberList = subscriberMap[msgTitle];
- if (!subscriberList || !subscriberList.length) return;
- for (let subscriber of subscriberList) {
- try {
- if (!subscriber || !subscriber.onGetMessage) continue;
- subscriber.onGetMessage(msgData);
- } catch (ex) {
- logger.error(ex);
- }
- }
- };
- };
- //MessageSubscriber
- sers.MessageSubscriber = function (subscriberManage, msgTitle, onGetMessage) {
- this.msgTitle = msgTitle;
- // bytes=>void
- this.onGetMessage = onGetMessage;
- this.subscribe = function () {
- subscriberManage.message_Subscribe(this);
- return this;
- };
- this.unSubscribe = function () {
- subscriberManage.message_UnSubscribe(this);
- return this;
- };
- };
- //LocalApiService
- sers.LocalApiService = function () {
- var self = this;
- // route_httpMethod -> ApiNode
- // ApiNode: { apiDesc,onInvoke,onInvokeAsync } //onInvoke 和 onInvokeAsync 指定其一即可
- // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
- // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
- // onInvokeFinish :(replyData_bytes)=>{ }
- var apiNodeMap = {};
- //return [ ApiNode ];
- //ApiNode {apiDesc:apiDesc }
- self.getApiNodes = function () {
- var apiNodes = [];
- for (var key in apiNodeMap) {
- apiNodes.push({ apiDesc: apiNodeMap[key].apiDesc });
- }
- return apiNodes;
- };
- //清空已加载的apiNode
- self.clearApiNodes = function () {
- apiNodeMap = {};
- };
- // ApiNode: { apiDesc,onInvoke,onInvokeAsync } //onInvoke 和 onInvokeAsync 指定其一即可
- // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
- // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
- // onInvokeFinish :(replyData_bytes)=>{ }
- self.addApiNode = function (apiNode) {
- var apiKey = apiNode.apiDesc.route + '_' + apiNode.apiDesc.extendConfig.httpMethod;
- apiNodeMap[apiKey] = apiNode;
- };
- // apiInvoke {route: '/JsStation/api', httpMethod: 'GET', name: 'call api in js server', description: 'js作为服务站点', onInvoke,onInvokeAsync}
- // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
- // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
- // onInvokeFinish :(replyData_bytes)=>{ }
- self.addApiInvoke = function (apiInvoke) {
- var apiDesc = {
- route: apiInvoke.route,
- name: apiInvoke.name,
- description: apiInvoke.description,
- extendConfig: {
- httpMethod: apiInvoke.httpMethod
- }
- };
- self.addApiNode({ apiDesc: apiDesc, onInvoke: apiInvoke.onInvoke, onInvokeAsync: apiInvoke.onInvokeAsync });
- };
- // apiInvoke {route: '/JsStation/api', httpMethod: 'GET', name: 'call api in js server', description: 'js作为服务站点', onInvoke,onInvokeAsync}
- // onInvoke: (requestData_bytes,rpcData_object,replyRpcData_object)=>{ return replyData_bytes; } //onInvoke 和 onInvokeAsync 指定其一即可
- // onInvokeAsync: (requestData_bytes,rpcData_object,replyRpcData_object,onInvokeFinish)=>{ }
- // onInvokeFinish :(replyData_bytes)=>{ }
- self.addApiInvokeArray = function (apiInvokeArray) {
- for (var apiInvoke of apiInvokeArray) {
- self.addApiInvoke(apiInvoke);
- }
- };
- //(Error e,requestData_bytes,rpcData_object,replyRpcData_object)
- //localApiService.onError = (e,requestData_bytes,rpcData_object,replyRpcData_object)=>{ return {success:false}; }
- self.onError = function (e, requestData_bytes, rpcData_object, replyRpcData_object) {
- logger.error(e);
- var reply = {
- success: false,
- error: {
- errorMessage: e.message,
- errorDetail: { name: e.name, stack: e.stack }
- }
- };
- return reply;
- };
- //invoke local api
- //callback: (apiReplyMessage_bytes)=>{ }
- self.invokeApiAsync = (apiRequestMessage_bytes, callback) => {
- //(x.1) 解析请求数据
- var apiMessage = new ApiMessage();
- apiMessage.unpackage(apiRequestMessage_bytes);
- var rpcData_object = apiMessage.getRpcData();
- var requestData_bytes = apiMessage.getValueBytes();
- //(x.2)解析路由获得 处理函数
- var route = rpcData_object.route;
- var httpMethod = rpcData_object.http.method;
- var apiKey = route + '_' + httpMethod;
- var apiNode = apiNodeMap[apiKey];
- //(x.3)进行处理获得结果数据
- var replyRpcData_object = {}, replyData_bytes;
- var onInvokeFinish = (replyData_bytes) => {
- //返回结果数据
- var apiReplyMessage_bytes = ApiMessage.package(
- vit.objectSerializeToBytes(replyRpcData_object),
- replyData_bytes
- );
- callback(apiReplyMessage_bytes);
- };
- if (apiNode) {
- try {
- if (apiNode.onInvoke) {
- replyData_bytes = apiNode.onInvoke(requestData_bytes, rpcData_object, replyRpcData_object);
- } else if (apiNode.onInvokeAsync) {
- apiNode.onInvokeAsync(requestData_bytes, rpcData_object, replyRpcData_object, onInvokeFinish);
- return;
- }
- } catch (e) {
- var reply = self.onError(e, requestData_bytes, rpcData_object, replyRpcData_object);
- replyData_bytes = vit.objectSerializeToBytes(reply);
- }
- } else {
- var reply = {
- success: false,
- error: {
- errorCode: 404,
- errorMessage: "Api Not Found",
- errorDetail: { source: 'from JsStation' }
- }
- };
- replyData_bytes = vit.objectSerializeToBytes(reply);
- }
- onInvokeFinish(replyData_bytes);
- };
- };
- //ServiceStation
- // localApiService org apiClient serviceStationInfo
- sers.ServiceStation = function () {
- var self = this;
- //(x.1) localApiService
- (function () {
- self.localApiService = new sers.LocalApiService();
- })();
- //(x.2) OrganizeClient self.org
- (function () {
- self.org = new sers.CL.OrganizeClient("ws://127.0.0.1:4503");
- //self.org.event_onDisconnected = function () {
- // logger.info('[sers.CL]org.event_onDisconnected');
- //};
- self.org.event_onGetRequest = self.localApiService.invokeApiAsync;
- })();
- //(x.3) apiClient
- (function () {
- self.apiClient = new sers.ApiClient(self.org);
- })();
- //(x.4) subscriberManage
- (function () {
- let messageClient = new sers.MessageClient(self.org);
- self.subscriberManage = new sers.SubscriberManage(messageClient);
- self.org.event_onGetMessage = messageClient.onGetMessage;
- })();
- //(x.5)
- self.stop = function () {
- logger.info('[sers.ServiceStation] try stop...');
- self.org.stop();
- logger.info('[sers.ServiceStation] stoped.');
- };
- //(x.6)
- self.serviceStationInfo = {
- serviceStationName: 'JsStation', serviceStationKey: '', stationVersion: '', info: {}
- };
- //(x.7)
- var deviceInfo = { deviceKey: ('' + Math.random()).substr(2) };
- //(x.8)
- //callback: function(success){}
- self.start = function (callback) {
- logger.info('[sers.CL] try connect...');
- self.org.connect(function (success) {
- if (!success) {
- logger.info('[sers.CL] org cannot connect to server!');
- if (callback) callback(false);
- return;
- }
- //向服务中心注册localApiService
- logger.info('[ServiceStation] regist serviceStation to ServiceCenter...');
- var apiNodes = self.localApiService.getApiNodes();
- var serviceStationData = {
- serviceStationInfo: self.serviceStationInfo,
- deviceInfo: deviceInfo,
- apiNodes: apiNodes
- };
- //(string route, object arg, string httpMethod, function callback)
- // callback: function({success,replyData_bytes,replyRpcData_object})
- self.apiClient.callApiAsync("/_sys_/serviceStation/regist", serviceStationData, 'POST', function (args) {
- let success = args.success, replyData_bytes = args.replyData_bytes, replyRpcData_object = args.replyRpcData_object;
- if (!success) {
- logger.info("[ServiceStation] regist - failed");
- if (callback) callback(false);
- return;
- }
- var apiRet = vit.bytesToObject(replyData_bytes);
- if (!apiRet.success) {
- logger.info("[ServiceStation] regist - failed. reply:" + vit.bytesToString(replyData_bytes));
- if (callback) callback(false);
- return;
- }
- logger.info("[ServiceStation] regist - succeed");
- if (callback) callback(true);
- });
- });
- };
- }
- })(sers);
|