[adapters] 增加对多线程 WebSocket 的支持

This commit is contained in:
SmallMain 2024-11-29 10:26:50 +08:00
parent 8b254fb84d
commit 203e5e290f
No known key found for this signature in database
5 changed files with 166 additions and 7 deletions

View File

@ -14,3 +14,8 @@ if (globalThis.CC_WORKER_HTTP_REQUEST) {
const http = require("./http-worker.js"); const http = require("./http-worker.js");
registerHandler("http", http); registerHandler("http", http);
} }
if (globalThis.CC_WORKER_WEBSOCKET) {
const ws = require("./ws-worker.js");
registerHandler("ws", ws);
}

View File

@ -0,0 +1,58 @@
const { main } = require("./ipc-worker.js");
var ws_worker = {
sockets: {},
connectSocket(id, url, protocols) {
try {
const ws = worker.connectSocket({
url,
protocols,
tcpNoDelay: true,
});
this.sockets[id] = ws;
ws.onOpen(() => {
main.wsAdapter.onOpen(id);
});
ws.onMessage(res => {
main.wsAdapter.onMessage(id, hookWSRecv ? hookWSRecv(res.data) : res.data);
});
ws.onError(res => {
delete this.sockets[id];
main.wsAdapter.onError(id, res);
});
ws.onClose(res => {
delete this.sockets[id];
main.wsAdapter.onClose(id, res);
});
} catch (error) {
main.wsAdapter.onError(id, { errMsg: String(error) });
}
},
send(id, data) {
const ws = this.sockets[id];
if (ws) {
ws.send({
data: hookWSSend ? hookWSSend(data) : data,
});
}
},
close(id, code, reason) {
const ws = this.sockets[id];
if (ws) {
ws.close({
code,
reason,
});
}
},
};
module.exports = ws_worker;

View File

@ -9,3 +9,8 @@ if (CC_WORKER_AUDIO_SYSTEM) {
ipcMain.registerHandler("audioAdapter", audioWorkerAdapter); ipcMain.registerHandler("audioAdapter", audioWorkerAdapter);
} }
} }
if (CC_WORKER_WEBSOCKET) {
const wsWorkerAdapter = require("./ws.js");
ipcMain.registerHandler("wsAdapter", wsWorkerAdapter);
}

View File

@ -0,0 +1,87 @@
let _id = 0;
class WorkerWebSocket {
id = _id++;
onopen = null;
onclose = null;
onerror = null;
onmessage = null;
constructor(url, protocols) {
wsWorkerAdapter.register(this);
worker.ws.connectSocket([this.id, url, protocols]);
}
onOpen(cb) {
this.onopen = cb;
}
onMessage(cb) {
this.onmessage = cb;
}
onClose(cb) {
this.onclose = cb;
}
onError(cb) {
this.onerror = cb;
}
send(res) {
worker.ws.send([this.id, res.data]);
}
close(res) {
worker.ws.close([this.id, res.code, res.reason]);
}
}
var wsWorkerAdapter = {
sockets: {},
register(socket) {
this.sockets[socket.id] = socket;
},
onOpen(args, cmdId, callback) {
const id = args[0];
const ws = this.sockets[id];
if (ws) {
ws.onopen?.();
}
},
onMessage(args, cmdId, callback) {
const id = args[0];
const data = args[1];
const ws = this.sockets[id];
if (ws) {
ws.onmessage?.({ data });
}
},
onClose(args, cmdId, callback) {
const id = args[0];
const data = args[1];
const ws = this.sockets[id];
if (ws) {
ws.onclose?.(data);
delete this.sockets[id];
}
},
onError(args, cmdId, callback) {
const id = args[0];
const data = args[1];
const ws = this.sockets[id];
if (ws) {
ws.onerror?.(data);
delete this.sockets[id];
}
},
};
globalThis.WorkerWebSocket = WorkerWebSocket;
module.exports = wsWorkerAdapter;

View File

@ -26,11 +26,13 @@ export default class WebSocket {
this.url = url this.url = url
this.readyState = WebSocket.CONNECTING this.readyState = WebSocket.CONNECTING
const socketTask = wx.connectSocket({ const socketTask = CC_WORKER_WEBSOCKET
? new WorkerWebSocket(url, Array.isArray(protocols) ? protocols : [protocols])
: wx.connectSocket({
url, url,
protocols: Array.isArray(protocols) ? protocols : [protocols], protocols: Array.isArray(protocols) ? protocols : [protocols],
tcpNoDelay: true tcpNoDelay: true
}) });
_socketTask.set(this, socketTask) _socketTask.set(this, socketTask)
@ -74,9 +76,11 @@ export default class WebSocket {
} }
send(data) { send(data) {
if (!CC_WORKER_WEBSOCKET) {
if (typeof data !== 'string' && !(data instanceof ArrayBuffer) && !ArrayBuffer.isView(data)) { if (typeof data !== 'string' && !(data instanceof ArrayBuffer) && !ArrayBuffer.isView(data)) {
throw new TypeError(`Failed to send message: The data ${data} is invalid`) throw new TypeError(`Failed to send message: The data ${data} is invalid`)
} }
}
const socketTask = _socketTask.get(this) const socketTask = _socketTask.get(this)