diff --git a/src/platforms/h5/service/api/network/socket.js b/src/platforms/h5/service/api/network/socket.js index b28a3c2481d19e65dbf4c4c697b085873f89b77b..5bd2ae3efac093d5148bf401199304ff4e67b59d 100644 --- a/src/platforms/h5/service/api/network/socket.js +++ b/src/platforms/h5/service/api/network/socket.js @@ -1,4 +1,9 @@ -var socketTask +const { + invokeCallbackHandler: invoke +} = UniServiceJSBridge +const eventNames = ['open', 'close', 'error', 'message'] +const callbacks = {} +const socketTasks = [] /** * SocketTask */ @@ -12,15 +17,55 @@ class SocketTask { * @param {string} url * @param {Array} protocols */ - constructor (url, protocols) { - this._webSocket = new WebSocket(url, protocols) + constructor (url, protocols, callback) { + let error + try { + const webSocket = this._webSocket = new WebSocket(url, protocols) + webSocket.binaryType = 'arraybuffer' + this._callbacks = {} + eventNames.forEach(name => { + this._callbacks[name] = [] + webSocket.addEventListener(name, event => { + const res = name === 'message' ? { + data: event.data + } : {} + this._callbacks[name].forEach(callback => { + try { + callback(res) + } catch (e) { + console.error(`thirdScriptError\n${e};at socketTask.on${name[0].toUpperCase() + name.substr(1)} callback function\n`, e) + } + }) + if (this === socketTasks[0] && callbacks[name]) { + invoke(callbacks[name], res) + } + if (name === 'error' || name === 'close') { + const index = socketTasks.indexOf(this) + if (index >= 0) { + socketTasks.splice(index, 1) + } + } + }) + }) + let propertys = ['CLOSED', 'CLOSING', 'CONNECTING', 'OPEN', 'readyState'] + propertys.forEach((property) => { + Object.defineProperty(this, property, { + get () { + return webSocket[property] + } + }) + }) + } catch (e) { + error = e + } + callback(error, this) } /** * 发送 * @param {any} data */ send (options = {}) { - var data = options.data + const data = options.data const ws = this._webSocket try { ws.send(data) @@ -35,60 +80,19 @@ class SocketTask { * @param {string} reason */ close (options = {}) { - var code = options.data - var reason = options.data const ws = this._webSocket + const arrgs = [] + arrgs.push(options.code || 1000) + if (typeof options.reason === 'string') { + arrgs.push(options.reason) + } try { - ws.close(code, reason) + ws.close(...arrgs) this._callback(options, 'sendSocketMessage:ok') } catch (error) { this._callback(options, `sendSocketMessage:fail ${error}`) } } - /** - * 监听开启 - * @param {Function} callback - */ - onOpen (callback) { - this._on('open', callback) - } - /** - * 监听关闭 - * @param {Function} callback - */ - onClose (callback) { - this._on('close', callback) - } - /** - * 监听错误 - * @param {Function} callback - */ - onError (callback) { - this._on('error', callback) - } - /** - * 监听消息 - * @param {Function} callback - */ - onMessage (callback) { - this._on('message', callback) - } - /** - * 监听事件 - * @param {string} eventName - * @param {Function} callback - */ - _on (eventName, callback) { - this._webSocket.addEventListener(eventName, event => { - if (eventName === 'message') { - callback({ - data: event.data - }) - } else { - callback() - } - }, false) - } /** * 通用回调处理 */ @@ -97,7 +101,7 @@ class SocketTask { fail, complete }, errMsg) { - var data = { + const data = { errMsg } if (/:ok$/.test(errMsg)) { @@ -114,7 +118,12 @@ class SocketTask { } } } - +eventNames.forEach(item => { + const name = item[0].toUpperCase() + item.substr(1) + SocketTask.prototype[`on${name}`] = function (callback) { + this._callbacks[item].push(callback) + } +}) /** * 创建一个 WebSocket 连接 * @param {any} data 数据 @@ -124,16 +133,14 @@ export function connectSocket ({ url, protocols }, callbackId) { - const { - invokeCallbackHandler: invoke - } = UniServiceJSBridge - socketTask = new SocketTask(url, protocols) - setTimeout(() => { + return new SocketTask(url, protocols, (error, socketTask) => { + if (!error) { + socketTasks.push(socketTask) + } invoke(callbackId, { - errMsg: 'connectSocket:ok' + errMsg: 'connectSocket:' + (error ? `fail ${error}` : 'ok') }) - }, 0) - return socketTask + }) } /** * 通过 WebSocket 连接发送数据 @@ -141,11 +148,9 @@ export function connectSocket ({ * @param {string} callbackId */ export function sendSocketMessage (options, callbackId) { - const { - invokeCallbackHandler: invoke - } = UniServiceJSBridge - if (socketTask && socketTask._webSocket.readyState === WebSocket.OPEN) { - socketTask.send(Object.assign(options, { + const socketTask = socketTasks[0] + if (socketTask && socketTask.readyState === socketTask.OPEN) { + socketTask.send(Object.assign({}, options, { complete (res) { invoke(callbackId, res) } @@ -162,11 +167,9 @@ export function sendSocketMessage (options, callbackId) { * @param {string} callbackId */ export function closeSocket (options, callbackId) { - const { - invokeCallbackHandler: invoke - } = UniServiceJSBridge - if (socketTask && socketTask._webSocket.readyState !== WebSocket.CLOSED) { - socketTask.close(Object.assign(options, { + const socketTask = socketTasks[0] + if (socketTask) { + socketTask.close(Object.assign({}, options, { complete (res) { invoke(callbackId, res) } @@ -182,34 +185,27 @@ export function closeSocket (options, callbackId) { * @param {string} method */ function on (method) { - const { - invokeCallbackHandler: invoke - } = UniServiceJSBridge return function (callbackId) { - if (socketTask) { - socketTask[method](function (res) { - invoke(callbackId, res) - }) - } + callbacks[method] = callbackId } } /** * 监听WebSocket连接打开事件 * @param {Function} cb */ -export const onSocketOpen = on('onOpen') +export const onSocketOpen = on('open') /** * 监听WebSocket错误 * @param {Function} cb */ -export const onSocketError = on('onError') +export const onSocketError = on('error') /** * 监听WebSocket接受到服务器的消息事件 * @param {Function} cb */ -export const onSocketMessage = on('onMessage') +export const onSocketMessage = on('message') /** * 监听WebSocket关闭 * @param {Function} callback */ -export const onSocketClose = on('onClose') +export const onSocketClose = on('close')