Files
NapCatQQ/src/common/server/websocket.ts
手瓜一十雪 7b09479cd2 fix: 拦截错误
2024-05-20 16:26:42 +08:00

106 lines
2.4 KiB
TypeScript

import { WebSocket, WebSocketServer } from 'ws';
import urlParse from 'url';
import { IncomingMessage } from 'node:http';
import { log } from '@/common/utils/log';
class WebsocketClientBase {
private wsClient: WebSocket | undefined;
constructor() {
}
send(msg: string) {
if (this.wsClient && this.wsClient.readyState == WebSocket.OPEN) {
this.wsClient.send(msg);
}
}
onMessage(msg: string) {
}
}
export class WebsocketServerBase {
private ws: WebSocketServer | null = null;
public token: string = '';
constructor() {
}
start(port: number, host: string = '') {
try {
this.ws = new WebSocketServer({
port,
host: '',
maxPayload: 1024 * 1024 * 1024
}).on('error', () => {
});
log(`ws服务启动成功, ${host}:${port}`);
} catch (e: any) {
throw Error('ws服务启动失败, 请检查监听的ip和端口' + e.toString());
}
this.ws.on('connection', (wsClient, req) => {
const url: string = req.url!.split('?').shift() || '/';
this.authorize(wsClient, req);
this.onConnect(wsClient, url, req);
wsClient.on('message', async (msg) => {
this.onMessage(wsClient, url, msg.toString());
});
});
}
stop() {
this.ws && this.ws.close((err) => {
log('ws server close failed!', err);
});
this.ws = null;
}
restart(port: number) {
this.stop();
this.start(port);
}
authorize(wsClient: WebSocket, req: IncomingMessage) {
const url = req.url!.split('?').shift();
log('ws connect', url);
let clientToken: string = '';
const authHeader = req.headers['authorization'];
if (authHeader) {
clientToken = authHeader.split('Bearer ').pop() || '';
log('receive ws header token', clientToken);
} else {
const parsedUrl = urlParse.parse(req.url || '/', true);
const urlToken = parsedUrl.query.access_token;
if (urlToken) {
if (Array.isArray(urlToken)) {
clientToken = urlToken[0];
} else {
clientToken = urlToken;
}
log('receive ws url token', clientToken);
}
}
if (this.token && clientToken != this.token) {
this.authorizeFailed(wsClient);
return wsClient.close();
}
}
authorizeFailed(wsClient: WebSocket) {
}
onConnect(wsClient: WebSocket, url: string, req: IncomingMessage) {
}
onMessage(wsClient: WebSocket, url: string, msg: string) {
}
sendHeart() {
}
}