feat: add showConnected option and refactor WebSocket connection handling

This commit is contained in:
2025-12-21 04:13:38 +08:00
parent 7975863af3
commit b6c613d601
4 changed files with 14 additions and 7 deletions

View File

@@ -1,7 +1,7 @@
import type { IncomingMessage, ServerResponse } from 'node:http'; import type { IncomingMessage, ServerResponse } from 'node:http';
import { handleServer } from './handle-server.ts'; import { handleServer } from './handle-server.ts';
import * as cookie from './cookie.ts'; import * as cookie from './cookie.ts';
import { ServerType, Listener, OnListener, ServerOpts, OnWebSocketOptions, OnWebSocketFn, WebScoketListenerFun, ListenerFun, HttpListenerFun, WS } from './server-type.ts'; import { ServerType, Listener, OnListener, ServerOpts, OnWebSocketOptions, OnWebSocketFn, WebSocketListenerFun, ListenerFun, HttpListenerFun, WS } from './server-type.ts';
import { parseIfJson } from '../utils/parse.ts'; import { parseIfJson } from '../utils/parse.ts';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
type CookieFn = (name: string, value: string, options?: cookie.SerializeOptions, end?: boolean) => void; type CookieFn = (name: string, value: string, options?: cookie.SerializeOptions, end?: boolean) => void;
@@ -64,11 +64,12 @@ export class ServerBase implements ServerType {
cors: Cors; cors: Cors;
listeners: Listener[] = []; listeners: Listener[] = [];
emitter = new EventEmitter(); emitter = new EventEmitter();
showConnected = true;
constructor(opts?: ServerOpts) { constructor(opts?: ServerOpts) {
this.path = opts?.path || '/api/router'; this.path = opts?.path || '/api/router';
this.handle = opts?.handle; this.handle = opts?.handle;
this.cors = opts?.cors; this.cors = opts?.cors;
this.showConnected = opts?.showConnected !== false;
} }
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void; listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
listen(port: number, hostname?: string, listeningListener?: () => void): void; listen(port: number, hostname?: string, listeningListener?: () => void): void;
@@ -202,7 +203,7 @@ export class ServerBase implements ServerType {
const end = (data: any) => { const end = (data: any) => {
ws.send(JSON.stringify(data)); ws.send(JSON.stringify(data));
} }
(listener.func as WebScoketListenerFun)({ (listener.func as WebSocketListenerFun)({
emitter: this.emitter, emitter: this.emitter,
data, data,
token, token,
@@ -275,4 +276,8 @@ export class ServerBase implements ServerType {
}, 5000); }, 5000);
} }
} }
async sendConnected(ws: WS) {
if (this.showConnected)
ws.send(JSON.stringify({ type: 'connected' }));
}
} }

View File

@@ -223,7 +223,7 @@ export class BunServer extends ServerBase implements ServerType {
}, },
websocket: { websocket: {
open: (ws: any) => { open: (ws: any) => {
ws.send(JSON.stringify({ type: 'connected' })); this.sendConnected(ws);
}, },
message: async (ws: any, message: string | Buffer) => { message: async (ws: any, message: string | Buffer) => {
const pathname = ws.data.pathname || ''; const pathname = ws.data.pathname || '';

View File

@@ -16,6 +16,7 @@ export type ServerOpts<T = {}> = {
handle?: (msg?: { path: string; key?: string;[key: string]: any }, ctx?: { req: http.IncomingMessage; res: http.ServerResponse }) => any; handle?: (msg?: { path: string; key?: string;[key: string]: any }, ctx?: { req: http.IncomingMessage; res: http.ServerResponse }) => any;
cors?: Cors; cors?: Cors;
io?: boolean; io?: boolean;
showConnected?: boolean;
} & T; } & T;
export interface ServerType { export interface ServerType {
@@ -40,11 +41,12 @@ export interface ServerType {
on(listener: OnListener): void; on(listener: OnListener): void;
onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void; onWebSocket({ ws, message, pathname, token, id }: OnWebSocketOptions): void;
onWsClose(ws: WS): void; onWsClose(ws: WS): void;
sendConnected(ws: WS): void;
} }
export type OnWebSocketOptions = { ws: WS; message: string | Buffer; pathname: string, token?: string, id?: string } export type OnWebSocketOptions = { ws: WS; message: string | Buffer; pathname: string, token?: string, id?: string }
export type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void; export type OnWebSocketFn = (options: OnWebSocketOptions) => Promise<void> | void;
export type WS = { export type WS<T = {}> = {
send: (data: any) => void; send: (data: any) => void;
close: (code?: number, reason?: string) => void; close: (code?: number, reason?: string) => void;
data?: { data?: {
@@ -56,7 +58,7 @@ export type WS = {
* 鉴权后的获取的信息 * 鉴权后的获取的信息
*/ */
userApp?: string; userApp?: string;
} } & T;
} }
export type Listener = { export type Listener = {
id?: string; id?: string;

View File

@@ -60,7 +60,7 @@ export class WsServerBase {
ws.on('message', async (message: string | Buffer) => { ws.on('message', async (message: string | Buffer) => {
await this.server.onWebSocket({ ws, message, pathname, token, id }); await this.server.onWebSocket({ ws, message, pathname, token, id });
}); });
ws.send(JSON.stringify({ type: 'connected' })); this.server.sendConnected(ws);
this.wss.on('close', () => { this.wss.on('close', () => {
this.server.onWsClose(ws); this.server.onWsClose(ws);
}); });