能否拦截修改发送至Node Inspector的消息/WebSocket并列出连接客户端?
解答你的Node Inspector WebSocket拦截与日志适配问题
完全可以实现你想要的功能!下面分点给你拆解解决方案:
一、拦截并修改发送到Node Inspector的WebSocket消息
Node.js官方提供的inspector模块,能让你直接和Inspector协议交互,甚至拦截、修改Node进程与DevTools之间传递的消息,完美适配你对日志格式的定制需求。
1. 基础实现:监听Inspector会话消息
你可以创建一个Inspector会话,监听所有发往DevTools的消息,针对性修改console.log/console.error这类日志的 payload——比如把TTY的颜色转义码转换成DevTools支持的%c样式格式。
示例代码如下:
const inspector = require('inspector'); const session = new inspector.Session(); session.connect(); // 监听所有发往客户端的Inspector通知 session.on('inspectorNotification', (message) => { if (message.method === 'Runtime.consoleAPICalled') { const args = message.params.args; // 遍历参数,把ANSI颜色转义码替换成DevTools样式 args.forEach(arg => { if (arg.type === 'string' && arg.value.includes('\x1b[')) { const colorMatch = arg.value.match(/\x1b\[(\d+)m(.*)\x1b\[0m/); if (colorMatch) { const [, ansiCode, text] = colorMatch; // 替换成%c格式,并插入样式参数 arg.value = `%c${text}`; args.splice(args.indexOf(arg) + 1, 0, { type: 'string', value: `color: ${mapAnsiToCss(ansiCode)};` }); } } }); // 若要完全接管日志发送,可取消原生console,通过session主动发送修改后的消息 } }); // 辅助函数:将ANSI颜色码映射为CSS颜色 function mapAnsiToCss(ansiCode) { switch(ansiCode) { case '31': return 'red'; case '32': return 'green'; case '33': return 'yellow'; case '34': return 'blue'; // 可根据需求扩展更多颜色映射 default: return 'inherit'; } }
2. 进阶方案:WebSocket代理服务器
如果需要更底层的控制(比如支持多客户端、全局日志拦截),可以启动一个WebSocket代理服务器,让DevTools连接到你的代理,再由代理转发Node Inspector的消息,同时在中间完成内容修改。这种方式灵活性更高。
二、区分TTY与DevTools的日志输出
核心思路是判断输出目标,分别适配格式:
- 针对TTY:直接使用
chalk生成带ANSI转义码的彩色日志; - 针对DevTools:将ANSI转义码转换成
console.log('%c', '样式')的格式。
你可以封装一个自定义日志函数,自动适配不同输出场景:
const chalk = require('chalk'); const inspector = require('inspector'); function customLog(message, style = 'red') { // 判断是否有DevTools连接 const hasDevTools = inspector.url() !== undefined; if (hasDevTools) { // 转换为DevTools支持的样式格式 const styledContent = convertChalkToDevTools(chalk[style](message)); console.log(...styledContent); } else { // 输出到TTY,保留chalk原生样式 console.log(chalk[style](message)); } } // 转换chalk输出到DevTools格式的辅助函数 function convertChalkToDevTools(chalkMsg) { const match = chalkMsg.match(/\x1b\[(\d+)m(.*)\x1b\[0m/); if (match) { return [`%c${match[2]}`, `color: ${mapAnsiToCss(match[1])};`]; } return [chalkMsg]; }
三、列出当前Node进程连接的WebSocket客户端
通过Node.js内部API,你可以直接获取已连接的DevTools客户端信息:
const { internalBinding } = require('process'); // 获取内部Inspector服务器实例 const inspectorServer = internalBinding('inspector').server; // 获取WebSocket客户端列表 const connectedClients = inspectorServer._wsServer.clients; console.log(`当前连接的DevTools客户端数量:${connectedClients.size}`); connectedClients.forEach(client => { console.log(`客户端地址:${client._socket.remoteAddress}`); }); // 监听客户端连接/断开事件 inspectorServer._wsServer.on('connection', (client) => { console.log(`新客户端连接:${client._socket.remoteAddress}`); client.on('close', () => { console.log(`客户端断开:${client._socket.remoteAddress}`); }); });
注意:internalBinding是Node.js内部API,不同版本可能存在兼容性差异,使用时需注意对应Node.js版本。
内容的提问来源于stack exchange,提问作者dwelle
相关产品推荐
相关产品推荐

