mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-16 04:45:46 +00:00
feat: a framework of passive (正向) websocket
This commit is contained in:
parent
33ef3e7d59
commit
8060b1c753
@ -26,7 +26,7 @@
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/qrcode-terminal": "^0.12.2",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@types/ws": "^8.5.12",
|
||||
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||
"@typescript-eslint/parser": "^7.4.0",
|
||||
"eslint": "^8.57.0",
|
||||
@ -46,6 +46,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^8.13.0",
|
||||
"async-mutex": "^0.5.0",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.1.0",
|
||||
"cors": "^2.8.5",
|
||||
@ -59,6 +60,6 @@
|
||||
"qrcode-terminal": "^0.12.0",
|
||||
"silk-wasm": "^3.6.1",
|
||||
"strtok3": "8.0.1",
|
||||
"ws": "^8.16.0"
|
||||
"ws": "^8.18.0"
|
||||
}
|
||||
}
|
||||
|
@ -4,4 +4,6 @@ import { OB11BaseEvent } from '@/onebot/event/OB11BaseEvent';
|
||||
export interface IOB11NetworkAdapter {
|
||||
registerAction<T extends BaseAction<P, R>, P, R>(action: T): void;
|
||||
onEvent<T extends OB11BaseEvent>(event: T): void;
|
||||
open(): void | Promise<void>;
|
||||
close(): void | Promise<void>;
|
||||
}
|
||||
|
72
src/onebot/network/passive-websocket.ts
Normal file
72
src/onebot/network/passive-websocket.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { IOB11NetworkAdapter } from './index';
|
||||
import { OB11BaseEvent } from '@/onebot/event/OB11BaseEvent';
|
||||
import BaseAction from '@/onebot/action/BaseAction';
|
||||
import { WebSocket, WebSocketServer } from 'ws';
|
||||
import { Mutex } from 'async-mutex';
|
||||
|
||||
export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
wsServer: WebSocketServer;
|
||||
wsClients: WebSocket[] = [];
|
||||
wsClientsMutex = new Mutex();
|
||||
isOpen: boolean = false;
|
||||
hasBeenClosed: boolean = false;
|
||||
|
||||
private actionMap: Map<string, BaseAction<any, any>> = new Map();
|
||||
|
||||
constructor(ip: string, port: number, token: string) {
|
||||
this.wsServer = new WebSocketServer({ port: port, host: ip });
|
||||
this.wsServer.on('connection', async (wsClient) => {
|
||||
if (!this.isOpen) {
|
||||
wsClient.close();
|
||||
return;
|
||||
}
|
||||
if (token) {
|
||||
const incomingToken = wsClient.url.split('?')[1]?.split('=')[1];
|
||||
if (incomingToken !== token) {
|
||||
wsClient.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
wsClient.on('message', (message) => {
|
||||
// TODO: extract action name and payload from the message, then call the corresponding action.
|
||||
});
|
||||
wsClient.once('close', () => {
|
||||
this.wsClientsMutex.runExclusive(async () => {
|
||||
const index = this.wsClients.indexOf(wsClient);
|
||||
if (index !== -1) {
|
||||
this.wsClients.splice(index, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
await this.wsClientsMutex.runExclusive(async () => {
|
||||
this.wsClients.push(wsClient);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerAction<T extends BaseAction<P, R>, P, R>(action: T) {
|
||||
this.actionMap.set(action.actionName, action);
|
||||
}
|
||||
|
||||
onEvent<T extends OB11BaseEvent>(event: T) {
|
||||
this.wsClientsMutex.runExclusive(async () => {
|
||||
this.wsClients.forEach((wsClient) => {
|
||||
// wsClient.send(JSON.stringify(event));
|
||||
// TODO: wrap the event, and send the wrapped to the client.
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
open() {
|
||||
if (this.hasBeenClosed) {
|
||||
throw new Error('Cannot open a closed WebSocket server');
|
||||
}
|
||||
this.isOpen = true;
|
||||
}
|
||||
|
||||
async close() {
|
||||
this.isOpen = false;
|
||||
this.hasBeenClosed = true;
|
||||
this.wsServer.close();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user