mtl-js-sdk
Version:
334 lines (270 loc) • 10 kB
JavaScript
"use strict";
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
module.exports = function (dependencies) {
var logger = dependencies.logger;
var PacketOpCode = {
auth: 0x0001,
ping: 0x0002,
message: 0x1010,
online: 0x1150,
receipt: 0x1002,
disconnect: 0x0004,
dataError: 0x4000,
connectError: 0x4100
};
var SocketClient =
/*#__PURE__*/
function () {
function SocketClient(url, onopen, onerror) {
var _this = this;
_classCallCheck(this, SocketClient);
var ws = new WebSocket(url, "xmpp");
ws.binaryType = "arraybuffer";
ws.onopen = function () {
onopen && onopen();
_this.makeHeartCheck();
};
ws.onerror = onerror;
ws.onmessage = function (event) {
var _this$_byteToJson = _this._byteToJson(event.data),
op = _this$_byteToJson.op,
json = _this$_byteToJson.json;
_this._dispatch(op, json);
_this.heartCheck.start();
};
this.ws = ws;
this.userinfo = null;
this.onerror = null;
this.onauth = null;
this.onmessage = null;
}
_createClass(SocketClient, [{
key: "makeHeartCheck",
value: function makeHeartCheck() {
//心跳检测
this.heartCheck = {
timeout: 5000,
timeoutObj: null,
serverTimeoutObj: null,
socket: null,
start: function start() {
var _this2 = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function () {
// 这里发送一个心跳,后端收到后,返回一个心跳消息
_this2.socket.send({}, PacketOpCode.ping);
_this2.serverTimeoutObj = setTimeout(function () {
_this2.socket.close();
}, _this2.timeout);
}, this.timeout);
},
stop: function stop() {
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
}
};
this.heartCheck.socket = this;
}
}, {
key: "close",
value: function close() {
this.heartCheck && this.heartCheck.stop();
this.heartCheck = null;
this.ws && this.ws.close();
this.ws = null;
}
}, {
key: "sendAuthPacket",
value: function () {
var _sendAuthPacket = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(_ref) {
var _this3 = this;
var usr, atk, deviceId, deviceName, json;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
usr = _ref.usr, atk = _ref.atk, deviceId = _ref.deviceId, deviceName = _ref.deviceName;
if (!(this.ws && this.ws.readyState == WebSocket.OPEN)) {
_context.next = 6;
break;
}
json = {
usr: usr,
atk: atk,
br: "web-v2.6",
isAuxiliaryDevice: true,
deviceIdentify: deviceId,
phoneModel: "web",
deviceName: deviceName
};
_context.next = 5;
return new Promise(function (resolve, reject) {
var taskid = setTimeout(function () {
reject("登录报文响应超时");
}, 3000);
_this3.onauth = function (json) {
clearTimeout(taskid);
_this3.onauth = null;
_this3.onerror = null;
resolve(json);
};
_this3.onerror = function (json) {
clearTimeout(taskid);
_this3.onauth = null;
_this3.onerror = null;
reject(json);
};
_this3.send(json, PacketOpCode.auth);
});
case 5:
return _context.abrupt("return", _context.sent);
case 6:
logger.error("socket == nil || socket.readyState != OPEN");
case 7:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function sendAuthPacket(_x) {
return _sendAuthPacket.apply(this, arguments);
}
return sendAuthPacket;
}()
}, {
key: "send",
value: function send(json, op) {
if (this.ws && this.ws.readyState == WebSocket.OPEN) {
logger.info("发送报文, op == " + op, json);
this.ws.send(this._jsonToByte(json, op));
return;
}
logger.error("socket == nil || socket.readyState != OPEN");
} // MARK: - Private Methods
}, {
key: "_dispatch",
value: function _dispatch(op, json) {
logger.info("接收消息, op == " + op, json);
switch (op) {
case PacketOpCode.auth:
this.onauth && this.onauth(json);
break;
case PacketOpCode.ping:
// 心跳
break;
case PacketOpCode.message:
// 单聊消息
break;
case PacketOpCode.online:
// 用户上线,多端消息借用该 op
this.onmessage && this.onmessage(json);
break;
case PacketOpCode.receipt:
break;
case PacketOpCode.dataError:
break;
case PacketOpCode.disconnect:
logger.info("socket disconnect");
break;
case PacketOpCode.connectError:
this.onerror && this.onerror(json);
break;
default:
logger.info("未知类型消息, op == " + op, json);
break;
}
}
}, {
key: "_numToBytes",
value: function _numToBytes(num, size) {
var bytes = new Array(size);
var i = size;
do {
bytes[--i] = num & 0xff;
num = num >> 8;
} while (i);
return bytes;
}
}, {
key: "_bytesToNum",
value: function _bytesToNum(bytes) {
var num = 0;
for (var i = 0; i < bytes.length; i++) {
if (i > 0) {
num *= 0x100;
}
num += bytes[i];
}
return num;
}
}, {
key: "_stringToUtf8Bytes",
value: function _stringToUtf8Bytes(str) {
var result = new Array();
var k = 0;
for (var i = 0; i < str.length; i++) {
var j = encodeURI(str[i]);
if (j.length == 1) {
result[k++] = j.charCodeAt(0);
} else {
var bytes = j.split("%");
for (var l = 1; l < bytes.length; l++) {
result[k++] = parseInt("0x" + bytes[l]);
}
}
}
return result;
}
}, {
key: "_jsonToByte",
value: function _jsonToByte(json, op) {
var body = JSON.stringify(json);
var bodyBytes = this._stringToUtf8Bytes(body);
var opBytes = this._numToBytes(op, 2);
var lengthBytes = this._numToBytes(bodyBytes.length, 4);
var headerBytes = [0].concat(opBytes).concat(lengthBytes).concat([1, 0, 0, 0, 0, 0]);
var bytes = headerBytes.concat(bodyBytes);
var buffer = new ArrayBuffer(bytes.length);
var obj = new DataView(buffer);
for (var i = 0; i < bytes.length; i++) {
obj.setUint8(i, bytes[i]);
}
return obj.buffer;
}
}, {
key: "_byteToJson",
value: function _byteToJson(data) {
var buffer = data;
var dataview = new DataView(buffer);
var header = new Array(13);
var body = "";
for (var i = 0; i < buffer.byteLength; i++) {
if (i < header.length) {
header[i] = dataview.getUint8(i);
} else {
body += String.fromCharCode(dataview.getUint8(i));
}
}
var op = this._bytesToNum(header.slice(1, 3));
var json = null;
try {
json = JSON.parse(decodeURIComponent(escape(body)));
} catch (_) {}
return {
json: json,
op: op
};
}
}]);
return SocketClient;
}();
return SocketClient;
};