@@ -10,16 +10,24 @@ import {toBeijingTime} from "../utils/datetime-format.js";
1010// WebSocket 客户端管理
1111const wsClients = new Set ( ) ;
1212
13+ // 需要拦截的console方法列表
14+ const CONSOLE_METHODS = [
15+ 'log' , 'error' , 'warn' , 'info' , 'debug' ,
16+ 'time' , 'timeEnd' , 'timeLog' ,
17+ 'assert' , 'clear' , 'count' , 'countReset' ,
18+ 'dir' , 'dirxml' , 'group' , 'groupCollapsed' , 'groupEnd' ,
19+ 'table' , 'trace' , 'profile' , 'profileEnd'
20+ ] ;
21+
1322// 原始 console 方法备份
14- const originalConsole = {
15- log : console . log ,
16- error : console . error ,
17- warn : console . warn ,
18- info : console . info ,
19- debug : console . debug ,
20- time : console . time ,
21- timeEnd : console . timeEnd ,
22- } ;
23+ const originalConsole = { } ;
24+
25+ // 动态备份所有console方法
26+ CONSOLE_METHODS . forEach ( method => {
27+ if ( typeof console [ method ] === 'function' ) {
28+ originalConsole [ method ] = console [ method ] ;
29+ }
30+ } ) ;
2331
2432// 广播消息到所有 WebSocket 客户端
2533function broadcastToClients ( message ) {
@@ -66,24 +74,22 @@ function interceptConsole() {
6674 } ;
6775 } ;
6876
69- console . log = createInterceptor ( 'log' , originalConsole . log ) ;
70- console . error = createInterceptor ( 'error' , originalConsole . error ) ;
71- console . warn = createInterceptor ( 'warn' , originalConsole . warn ) ;
72- console . info = createInterceptor ( 'info' , originalConsole . info ) ;
73- console . debug = createInterceptor ( 'debug' , originalConsole . debug ) ;
74- console . time = createInterceptor ( 'time' , originalConsole . time ) ;
75- console . timeEnd = createInterceptor ( 'timeEnd' , originalConsole . timeEnd ) ;
77+ // 动态拦截所有console方法
78+ CONSOLE_METHODS . forEach ( method => {
79+ if ( originalConsole [ method ] ) {
80+ console [ method ] = createInterceptor ( method , originalConsole [ method ] ) ;
81+ }
82+ } ) ;
7683}
7784
7885// 恢复原始 console
7986function restoreConsole ( ) {
80- console . log = originalConsole . log ;
81- console . error = originalConsole . error ;
82- console . warn = originalConsole . warn ;
83- console . info = originalConsole . info ;
84- console . debug = originalConsole . debug ;
85- console . time = originalConsole . time ;
86- console . timeEnd = originalConsole . timeEnd ;
87+ // 动态恢复所有console方法
88+ CONSOLE_METHODS . forEach ( method => {
89+ if ( originalConsole [ method ] ) {
90+ console [ method ] = originalConsole [ method ] ;
91+ }
92+ } ) ;
8793}
8894
8995// 启动 console 拦截
@@ -96,98 +102,96 @@ interceptConsole();
96102 * @param {Function } done - 完成回调
97103 */
98104export default ( fastify , options , done ) => {
99- // 注册WebSocket路由
100- // fastify.register(async function (fastify) {
101- /**
102- * WebSocket连接路由
103- * GET /ws - 建立WebSocket连接
104- */
105- fastify . get ( '/ws' , { websocket : true } , ( socket , req ) => {
106- const clientId = Date . now ( ) + Math . random ( ) ;
107- originalConsole . log ( `WebSocket client connected: ${ clientId } ` ) ;
108- originalConsole . log ( 'Socket type:' , typeof socket ) ;
109- originalConsole . log ( 'Socket has send method:' , typeof socket . send ) ;
110-
111- // 添加到客户端集合
112- wsClients . add ( socket ) ;
113-
114- // 设置连接属性
115- socket . clientId = clientId ;
116- socket . isAlive = true ;
117- socket . lastPing = Date . now ( ) ;
118-
119- // 发送欢迎消息 - 先检查send方法是否存在
120- if ( typeof socket . send === 'function' ) {
121- socket . send ( JSON . stringify ( {
122- type : 'welcome' ,
123- message : 'WebSocket connection established' ,
124- clientId : clientId ,
125- timestamp : Date . now ( )
126- } ) ) ;
127- } else {
128- originalConsole . error ( 'Socket does not have send method' ) ;
105+ /**
106+ * WebSocket连接路由
107+ * GET /ws - 建立WebSocket连接
108+ */
109+ fastify . get ( '/ws' , { websocket : true } , ( socket , req ) => {
110+ const clientId = Date . now ( ) + Math . random ( ) ;
111+ originalConsole . log ( `WebSocket client connected: ${ clientId } ` ) ;
112+ originalConsole . log ( 'Socket type:' , typeof socket ) ;
113+ originalConsole . log ( 'Socket has send method:' , typeof socket . send ) ;
114+
115+ // 添加到客户端集合
116+ wsClients . add ( socket ) ;
117+
118+ // 设置连接属性
119+ socket . clientId = clientId ;
120+ socket . isAlive = true ;
121+ socket . lastPing = Date . now ( ) ;
122+
123+ // 发送欢迎消息 - 先检查send方法是否存在
124+ if ( typeof socket . send === 'function' ) {
125+ socket . send ( JSON . stringify ( {
126+ type : 'welcome' ,
127+ message : 'WebSocket connection established' ,
128+ clientId : clientId ,
129+ timestamp : Date . now ( )
130+ } ) ) ;
131+ } else {
132+ originalConsole . error ( 'Socket does not have send method' ) ;
133+ }
134+
135+ // 设置心跳检测
136+ const heartbeatInterval = setInterval ( ( ) => {
137+ if ( ! socket . isAlive ) {
138+ originalConsole . log ( `Client ${ clientId } failed heartbeat, terminating` ) ;
139+ clearInterval ( heartbeatInterval ) ;
140+ wsClients . delete ( socket ) ; // 修复内存泄露:从客户端集合中移除
141+ socket . terminate ( ) ;
142+ return ;
129143 }
130144
131- // 设置心跳检测
132- const heartbeatInterval = setInterval ( ( ) => {
133- if ( ! socket . isAlive ) {
134- originalConsole . log ( `Client ${ clientId } failed heartbeat, terminating` ) ;
135- clearInterval ( heartbeatInterval ) ;
136- socket . terminate ( ) ;
137- return ;
138- }
145+ socket . isAlive = false ;
146+ socket . ping ( ) ;
147+ } , 30000 ) ; // 30秒心跳检测
148+
149+ // 处理pong响应
150+ socket . on ( 'pong' , ( ) => {
151+ socket . isAlive = true ;
152+ } ) ;
139153
140- socket . isAlive = false ;
141- socket . ping ( ) ;
142- } , 30000 ) ; // 30秒心跳检测
143-
144- // 处理pong响应
145- socket . on ( 'pong' , ( ) => {
146- socket . isAlive = true ;
147- } ) ;
148-
149- // 处理消息
150- socket . on ( 'message' , ( message ) => {
151- try {
152- const data = JSON . parse ( message . toString ( ) ) ;
153- originalConsole . log ( `Received from ${ clientId } :` , data ) ;
154-
155- // 回显消息
156- if ( socket . readyState === socket . OPEN ) {
157- socket . send ( JSON . stringify ( {
158- type : 'echo' ,
159- originalMessage : data ,
160- timestamp : Date . now ( ) ,
161- clientId : clientId
162- } ) ) ;
163- }
164- } catch ( error ) {
165- originalConsole . error ( 'Error processing message:' , error ) ;
166- if ( socket . readyState === socket . OPEN ) {
167- socket . send ( JSON . stringify ( {
168- type : 'error' ,
169- message : 'Invalid JSON format' ,
170- timestamp : Date . now ( )
171- } ) ) ;
172- }
154+ // 处理消息
155+ socket . on ( 'message' , ( message ) => {
156+ try {
157+ const data = JSON . parse ( message . toString ( ) ) ;
158+ originalConsole . log ( `Received from ${ clientId } :` , data ) ;
159+
160+ // 回显消息
161+ if ( socket . readyState === socket . OPEN ) {
162+ socket . send ( JSON . stringify ( {
163+ type : 'echo' ,
164+ originalMessage : data ,
165+ timestamp : Date . now ( ) ,
166+ clientId : clientId
167+ } ) ) ;
168+ }
169+ } catch ( error ) {
170+ originalConsole . error ( 'Error processing message:' , error ) ;
171+ if ( socket . readyState === socket . OPEN ) {
172+ socket . send ( JSON . stringify ( {
173+ type : 'error' ,
174+ message : 'Invalid JSON format' ,
175+ timestamp : Date . now ( )
176+ } ) ) ;
173177 }
174- } ) ;
178+ }
179+ } ) ;
175180
176- // 处理连接关闭
177- socket . on ( 'close' , ( code , reason ) => {
178- originalConsole . log ( `Client ${ clientId } disconnected: ${ code } ${ reason } ` ) ;
179- wsClients . delete ( socket ) ;
180- clearInterval ( heartbeatInterval ) ;
181- } ) ;
181+ // 处理连接关闭
182+ socket . on ( 'close' , ( code , reason ) => {
183+ originalConsole . log ( `Client ${ clientId } disconnected: ${ code } ${ reason } ` ) ;
184+ wsClients . delete ( socket ) ;
185+ clearInterval ( heartbeatInterval ) ;
186+ } ) ;
182187
183- // 处理错误
184- socket . on ( 'error' , ( error ) => {
185- originalConsole . error ( `WebSocket error for client ${ clientId } :` , error ) ;
186- wsClients . delete ( socket ) ;
187- clearInterval ( heartbeatInterval ) ;
188- } ) ;
188+ // 处理错误
189+ socket . on ( 'error' , ( error ) => {
190+ originalConsole . error ( `WebSocket error for client ${ clientId } :` , error ) ;
191+ wsClients . delete ( socket ) ;
192+ clearInterval ( heartbeatInterval ) ;
189193 } ) ;
190- // });
194+ } ) ;
191195
192196 /**
193197 * WebSocket状态查询接口
0 commit comments