From 17faa67eb0f72a5cb1755ac972fc401e6841c61f Mon Sep 17 00:00:00 2001 From: qiang Date: Tue, 30 Jul 2019 17:53:33 +0800 Subject: [PATCH] feat: app-plus socket feat: app-plus socket --- src/core/service/api/network/socket.js | 178 +++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/core/service/api/network/socket.js diff --git a/src/core/service/api/network/socket.js b/src/core/service/api/network/socket.js new file mode 100644 index 000000000..eece053fc --- /dev/null +++ b/src/core/service/api/network/socket.js @@ -0,0 +1,178 @@ +import { + invoke +} from 'uni-core/service/bridge' + +import { + onMethod, + invokeMethod +} from '../../platform' + +class SocketTask { + constructor (socketTaskId) { + this.id = socketTaskId + this._callbacks = { + open: [], + close: [], + error: [], + message: [] + } + this.CLOSED = 3 + this.CLOSING = 2 + this.CONNECTING = 0 + this.OPEN = 1 + this.readyState = this.CLOSED + } + send (args) { + if (this.readyState !== this.OPEN) { + this._callback(args, 'sendSocketMessage:fail WebSocket is not connected') + } + const { + errMsg + } = invokeMethod('operateSocketTask', Object.assign({}, args, { + operationType: 'send', + socketTaskId: this.id + })) + this._callback(args, errMsg.replace('operateSocketTask', 'sendSocketMessage')) + } + close (args) { + this.readyState = this.CLOSING + const { + errMsg + } = invokeMethod('operateSocketTask', Object.assign({}, args, { + operationType: 'close', + socketTaskId: this.id + })) + this._callback(args, errMsg.replace('operateSocketTask', 'closeSocket')) + } + onOpen (callback) { + this._callbacks.open.push(callback) + } + onClose (callback) { + this._callbacks.close.push(callback) + } + onError (callback) { + this._callbacks.error.push(callback) + } + onMessage (callback) { + this._callbacks.message.push(callback) + } + _callback ({ + success, + fail, + complete + }, errMsg) { + var data = { + errMsg + } + if (/:ok$/.test(errMsg)) { + if (typeof success === 'function') { + success(data) + } + } else { + if (typeof fail === 'function') { + fail(data) + } + } + if (typeof complete === 'function') { + complete(data) + } + } +} + +const socketTasks = Object.create(null) +const socketTasksArray = [] +const callbacks = Object.create(null) +onMethod('onSocketTaskStateChange', ({ + socketTaskId, + state, + data, + errMsg +}) => { + const socketTask = socketTasks[socketTaskId] + if (!socketTask) { + return + } + socketTask._callbacks[state].forEach(callback => { + if (typeof callback === 'function') { + callback(state === 'message' ? { + data + } : {}) + } + }) + if (state === 'open') { + socketTask.readyState = socketTask.OPEN + } + if (socketTask === socketTasksArray[0] && callbacks[state]) { + invoke(callbacks[state], state === 'message' ? { + data + } : {}) + } + if (state === 'error' || state === 'close') { + socketTask.readyState = socketTask.CLOSED + delete socketTasks[socketTaskId] + const index = socketTasksArray.indexOf(socketTask) + if (index >= 0) { + socketTasksArray.splice(index, 1) + } + } +}) + +export function connectSocket (args, callbackId) { + const { + socketTaskId + } = invokeMethod('createSocketTask', args) + const task = new SocketTask(socketTaskId) + socketTasks[socketTaskId] = task + socketTasksArray.push(task) + setTimeout(() => { + invoke(callbackId, { + errMsg: 'connectSocket:ok' + }) + }, 0) + return task +} + +export function sendSocketMessage (args, callbackId) { + const socketTask = socketTasksArray[0] + if (!socketTask || socketTask.readyState !== socketTask.OPEN) { + invoke(callbackId, { + errMsg: 'sendSocketMessage:fail WebSocket is not connected' + }) + return + } + return invokeMethod('operateSocketTask', Object.assign({}, args, { + operationType: 'send', + socketTaskId: socketTask.id + })) +} + +export function closeSocket (args, callbackId) { + const socketTask = socketTasksArray[0] + if (!socketTask) { + invoke(callbackId, { + errMsg: 'closeSocket:fail WebSocket is not connected' + }) + return + } + socketTask.readyState = socketTask.CLOSING + return invokeMethod('operateSocketTask', Object.assign({}, args, { + operationType: 'close', + socketTaskId: socketTask.id + })) +} + +export function onSocketOpen (callbackId) { + callbacks.open = callbackId +} + +export function onSocketError (callbackId) { + callbacks.error = callbackId +} + +export function onSocketMessage (callbackId) { + callbacks.message = callbackId +} + +export function onSocketClose (callbackId) { + callbacks.close = callbackId +} -- GitLab