Skills Plugins MCP Prompt Model 博客 我的中心

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 Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=agentworkforce-relay-claude-skills-debugging-websocket-issues-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
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)
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。