开发编程
#web
debugging-websocket-issues
Use when seeing WebSocket errors like "Invalid frame header", "RSV1 must be clear", or "WS_ERR_UNEXPECTED_RSV_1" - covers multiple WebSocketServer conflicts, compression issues, and raw frame debugging techniques
DeepseekModel
官方收录技能
质量 优秀 · 90
v1.0.0
获取
https://deepseekmodel.com/api/download.php?id=agentworkforce-relay-claude-skills-debugging-websocket-issues-skill-md&format=skill
下载 .skill
标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name debugging-websocket-issues description Use when seeing WebSocket errors like "Invalid frame header", "RSV1 must be clear", or "WS_ERR_UNEXPECTED_RSV_1" - covers multiple WebSocketServer conflicts, compression issues, and raw frame debugging techniques tags websocket, debugging, ws, node Debugging WebSocket Issues Overview WebSocket "invalid frame header" errors often stem from raw HTTP being written to an upgraded socket, not actual frame corruption. The most common cause is multiple WebSocketServer instances conflicting on the same HTTP server. When to Use Error: Invalid WebSocket frame: RSV1 must be clear Error: WS_ERR_UNEXPECTED_RSV_1 Error: Invalid frame header WebSocket connects then immediately disconnects with code 1006 Server logs success but client receives garbage data Quick Reference Symptom Likely Cause Fix RSV1 must be clear Multiple WSS on same server OR compression mismatch Use noServer: true mode Hex starts with 48545450 Raw HTTP on WebSocket (0x48='H') Check for conflicting upgrade handlers Code 1006, no reason Abnormal closure, often server-side abort Check abortHandshake calls Works isolated, fails in app Something else writing to socket Audit all upgrade listeners The Multiple WebSocketServer Bug Problem When attaching multiple WebSocketServer instances to the same HTTP server using the server option: // ❌ BAD - Both servers add upgrade listeners, causing conflicts const wss1 = new WebSocketServer ({ server, path : '/ws' }); const wss2 = new WebSocketServer ({ server, path : '/ws/other' }); What happens: Client connects to /ws BOTH upgrade handlers fire (Node.js EventEmitter calls all listeners) wss1 matches path, handles upgrade successfully wss2 doesn't match, calls abortHandshake(socket, 400) Raw HTTP/1.1 400 Bad Request written to the now-WebSocket socket Client receives HTTP text as WebSocket frame data First byte 0x48 ('H') interpreted as: RSV1=1, opcode=8 → invalid frame Solution Use noServer: true and manually route upgrades: // ✅ GOOD - Single upgrade handler routes to correct server const wss1 = new WebSocketServer ({ noServer : true , perMessageDeflate : false }); const wss2 = new WebSocketServer ({ noServer : true , perMessageDeflate : false }); server. on ( 'upgrade' , ( request, socket, head ) => { const pathname = new URL (request. url || '' , `http:// ${request.headers.host} ` ). pathname ; if (pathname === '/ws' ) { wss1. handleUpgrade (request, socket, head, ( ws ) => { wss1. emit ( 'connection' , ws, request); }); } else if (pathname === '/ws/other' ) { wss2. handleUpgrade (request, socket, head, ( ws ) => { wss2. emit ( 'connection' , ws, request); }); } else { socket. destroy (); } }); Debugging Techniques Raw Frame Inspection Hook into the socket to see actual bytes received: ws. on ( 'open' , () => { const socket = ws. _socket ; const originalPush = socket. push . bind (socket); socket. push = function ( chunk, encoding ) { if (chunk) { console . log ( 'First 20 bytes (hex):' , chunk. slice ( 0 , 20 ). toString ( 'hex' )); const byte0 = chunk[ 0 ]; console . log ( `FIN: ${!!(byte0 & 0x80 )} , RSV1: ${!!(byte0 & 0x40 )} , Opcode: ${byte0 & 0x0f } ` ); // Check if it's actually HTTP text if (chunk. slice ( 0 , 4 ). toString () === 'HTTP' ) { console . log ( '*** RECEIVED RAW HTTP ON WEBSOCKET ***' ); } } return originalPush (chunk, encoding); }; }); Key Hex Patterns 81 = FIN + text frame (normal) 82 = FIN + binary frame (normal) 88 = FIN + close frame (normal) 48545450 = "HTTP" - raw HTTP on WebSocket (bug!) c1 or similar with bit 6 set = compressed frame (RSV1=1) Common Mistakes Mistake Result Fix Multiple WSS with server option HTTP 400 written to socket Use noServer: true perMessageDeflate: true (default in older ws) RSV1 set on frames Explicitly set perMessageDeflate: false Not checking upgrade headers Miss compression negotiation Log sec-websocket-extensions header Assuming RSV1 error = compression Could be raw HTTP Check if bytes decode as ASCII "HTTP" Verification Checklist After fixing, verify: RSV1: false in frame inspection Extensions header: NONE in upgrade response No HTTP/1.1 in raw frame data Messages received match sent payload size Multiple broadcasts work (test interval sends)
Agent 识别该技能的关键词,点击任意一个即可复制。
该技能未提供触发词。
下载的 .skill 包内含以下字段。
| 字段 | 说明 |
|---|---|
| format | 格式标识(skill/v1) |
| skill_id | 技能唯一 ID |
| name | 技能名称 |
| version | 版本号 |
| description | 技能描述 |
| category | 所属分类(数组) |
| trigger_words | 触发词列表 |
| tags | 标签列表 |
| source | 来源标识 |
| source_url | 来源链接(本页地址) |
| exported_at | 导出时间(每次下载生成) |
| system_prompt | 系统提示词正文 |
| model_config | 模型参数:provider / model / temperature / max_tokens / top_p |
| examples | 示例 |
| install_guide | 各平台导入说明(Coze / Dify / Claude / 自定义框架) |