| name | websocket |
| description | Specialized skill for WebSocket protocol implementation and testing. Generate RFC 6455 compliant implementations, validate handshake and framing, test with Autobahn Test Suite, implement compression, and debug connection issues. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"real-time-communication","backlog-id":"SK-005"} |
| graph | {"domains":["domain:networking"],"specializations":["specialization:network-programming"],"skillAreas":["skill-area:protocol-design","skill-area:socket-programming","skill-area:websocket-design"],"roles":["role:backend-engineer","role:sre"],"topics":["topic:circuit-breakers"]} |
websocket
You are websocket - a specialized skill for WebSocket protocol implementation and testing, providing deep expertise in RFC 6455 compliance, real-time messaging, and performance optimization.
Overview
This skill enables AI-powered WebSocket operations including:
- Generating RFC 6455 compliant implementations
- Validating WebSocket handshake and framing
- Testing with Autobahn Test Suite
- Implementing permessage-deflate compression
- Debugging WebSocket connection issues
- Generating subprotocol handlers
- Analyzing WebSocket traffic
Prerequisites
- WebSocket-capable runtime (Node.js, Python, Go, etc.)
- Optional:
wscat or websocat for CLI testing
- Optional: Autobahn Test Suite for compliance testing
Capabilities
1. WebSocket Handshake
Implement RFC 6455 compliant handshake:
const crypto = require('crypto');
const http = require('http');
const WS_MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
function computeAcceptKey(secWebSocketKey) {
return crypto
.createHash('sha1')
.update(secWebSocketKey + WS_MAGIC_STRING)
.digest('base64');
}
function handleUpgrade(req, socket) {
if (req.headers['upgrade']?.toLowerCase() !== 'websocket') {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
return false;
}
const key = req.headers['sec-websocket-key'];
if (!key) {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
return false;
}
const keyBytes = Buffer.from(key, 'base64');
if (keyBytes.length !== 16) {
socket.();
;
}
acceptKey = (key);
requestedProtocols = req.[]?.().( p.()) || [];
selectedProtocol = (requestedProtocols);
response = [
,
,
,
];
(selectedProtocol) {
response.();
}
extensions = (req.[]);
(extensions) {
response.();
}
socket.(response.() + );
;
}
() {
supported = [, , ];
requested.( supported.(p)) || ;
}
() {
(extensionHeader?.()) {
;
}
;
}
2. WebSocket Frame Parsing
Parse and create WebSocket frames:
const OPCODES = {
CONTINUATION: 0x0,
TEXT: 0x1,
BINARY: 0x2,
CLOSE: 0x8,
PING: 0x9,
PONG: 0xA
};
class WebSocketFrame {
constructor() {
this.fin = true;
this.rsv1 = false;
this.rsv2 = false;
this.rsv3 = false;
this.opcode = OPCODES.TEXT;
this.masked = false;
this.maskingKey = null;
this.payload = Buffer.alloc(0);
}
static parse(buffer) {
if (buffer.length < 2) return { frame: null, : };
frame = ();
offset = ;
byte0 = buffer[offset++];
frame. = (byte0 & ) !== ;
frame. = (byte0 & ) !== ;
frame. = (byte0 & ) !== ;
frame. = (byte0 & ) !== ;
frame. = byte0 & ;
byte1 = buffer[offset++];
frame. = (byte1 & ) !== ;
payloadLength = byte1 & ;
(payloadLength === ) {
(buffer. < offset + ) { : , : };
payloadLength = buffer.(offset);
offset += ;
} (payloadLength === ) {
(buffer. < offset + ) { : , : };
high = buffer.(offset);
low = buffer.(offset + );
payloadLength = high * + low;
offset += ;
}
(frame.) {
(buffer. < offset + ) { : , : };
frame. = buffer.(offset, offset + );
offset += ;
}
(buffer. < offset + payloadLength) {
{ : , : };
}
frame. = buffer.(offset, offset + payloadLength);
offset += payloadLength;
(frame.) {
frame. = .(frame.);
( i = ; i < frame..; i++) {
frame.[i] ^= frame.[i % ];
}
}
{ frame, : offset };
}
() {
payloadLength = ..;
headerLength = ;
(payloadLength > ) headerLength += ;
(payloadLength > ) headerLength += ;
(mask) headerLength += ;
buffer = .(headerLength + payloadLength);
offset = ;
buffer[offset++] = (. ? : ) |
(. ? : ) |
(. ? : ) |
(. ? : ) |
.;
lengthByte = mask ? : ;
(payloadLength > ) {
lengthByte |= ;
buffer[offset++] = lengthByte;
buffer.(.(payloadLength / ), offset);
buffer.(payloadLength % , offset + );
offset += ;
} (payloadLength > ) {
lengthByte |= ;
buffer[offset++] = lengthByte;
buffer.(payloadLength, offset);
offset += ;
} {
lengthByte |= payloadLength;
buffer[offset++] = lengthByte;
}
(mask) {
maskingKey = crypto.();
maskingKey.(buffer, offset);
offset += ;
( i = ; i < payloadLength; i++) {
buffer[offset + i] = .[i] ^ maskingKey[i % ];
}
} {
..(buffer, offset);
}
buffer;
}
}
3. WebSocket Server Implementation
Complete WebSocket server:
const http = require('http');
const crypto = require('crypto');
const EventEmitter = require('events');
class WebSocketServer extends EventEmitter {
constructor(options = {}) {
super();
this.port = options.port || 8080;
this.maxPayload = options.maxPayload || 100 * 1024 * 1024;
this.clients = new Set();
this.server = http.createServer((req, res) => {
res.writeHead(426, { 'Content-Type': 'text/plain' });
res.end('WebSocket server - upgrade required');
});
this.server.on('upgrade', (req, socket, head) => {
this.handleUpgrade(req, socket, head);
});
}
() {
key = req.[];
(!key) {
socket.();
;
}
acceptKey = crypto
.()
.(key + )
.();
socket.([
,
,
,
,
,
].());
client = (socket, );
..(client);
client.(, {
..(client);
});
.(, client, req);
}
() {
( client .) {
(client !== excludeClient && client. === ) {
client.(message);
}
}
}
() {
..(., callback);
}
() {
( client .) {
client.(, );
}
..(callback);
}
}
{
() {
();
. = socket;
. = server;
. = ;
. = .();
. = [];
socket.(, .(data));
socket.(, .());
socket.(, .(, err));
}
() {
. = .([., data]);
(.. > ) {
{ frame, consumed } = .(.);
(!frame) ;
. = ..(consumed);
.(frame);
}
}
() {
(frame.) {
.:
.:
(frame.) {
data = frame. === .
? frame..()
: frame.;
.(, data);
} {
..(frame);
}
;
.:
..(frame);
(frame.) {
firstFrame = .[];
payload = .(..( f.));
data = firstFrame. === .
? payload.()
: payload;
.(, data);
. = [];
}
;
.:
.(frame.);
;
.:
.(, frame.);
;
.:
code = ;
reason = ;
(frame.. >= ) {
code = frame..();
reason = frame..().();
}
.(code, reason);
;
}
}
() {
(. !== ) ;
frame = ();
( data === ) {
frame. = .;
frame. = .(data, );
} {
frame. = .;
frame. = data;
}
..(frame.());
}
() {
frame = ();
frame. = .;
frame. = .(data) ? data : .(data);
..(frame.());
}
() {
frame = ();
frame. = .;
frame. = .(data) ? data : .(data);
..(frame.());
}
() {
(. === ) ;
. = ;
frame = ();
frame. = .;
codeBuffer = .();
codeBuffer.(code, );
reasonBuffer = .(reason, );
frame. = .([codeBuffer, reasonBuffer]);
..(frame.());
..();
}
() {
. = ;
.();
}
}
4. permessage-deflate Compression
Implement WebSocket compression:
const zlib = require('zlib');
class PerMessageDeflate {
constructor(options = {}) {
this.serverNoContextTakeover = options.serverNoContextTakeover || false;
this.clientNoContextTakeover = options.clientNoContextTakeover || false;
this.serverMaxWindowBits = options.serverMaxWindowBits || 15;
this.clientMaxWindowBits = options.clientMaxWindowBits || 15;
this.inflateContext = null;
this.deflateContext = null;
}
compress(data, callback) {
if (!this.deflateContext || this.serverNoContextTakeover) {
this.deflateContext = zlib.createDeflateRaw({
windowBits: this.serverMaxWindowBits
});
}
const chunks = [];
this.deflateContext.on('data', () => chunks.(chunk));
..(, {
result = .(chunks);
(result. >= &&
result[result. - ] === &&
result[result. - ] === &&
result[result. - ] === &&
result[result. - ] === ) {
result = result.(, -);
}
(, result);
});
..(data);
..(zlib.);
}
() {
(!. || .) {
. = zlib.({
: .
});
}
trailer = .([, , , ]);
input = .([data, trailer]);
chunks = [];
..(, chunks.(chunk));
..(, {
(, .(chunks));
});
..(, (err));
..(input);
..();
}
}
5. WebSocket Testing
Test WebSocket implementations:
wscat -c ws://localhost:8080
websocat ws://localhost:8080
docker run -it --rm \
-v "${PWD}/reports:/reports" \
-p 9001:9001 \
crossbario/autobahn-testsuite \
wstest --mode fuzzingclient --spec /config/fuzzingclient.json
MCP Server Integration
This skill can leverage the following MCP servers for enhanced capabilities:
| Server | Description | Integration |
|---|
| MCP-WebSocket Architecture | WebSocket transport with MCP | Real-time AI integration |
| claude-agent-server | WebSocket server for Claude Agent SDK | Agent orchestration |
| Claude-Flow | Multi-agent communication via WebSocket | Distributed agents |
Best Practices
- Handle fragmented messages - Large messages may be split across frames
- Implement heartbeat - Use ping/pong for connection health
- Set payload limits - Prevent memory exhaustion attacks
- Close gracefully - Send close frame before disconnecting
- Validate UTF-8 - Text frames must be valid UTF-8
- Handle backpressure - Don't overwhelm slow clients
Process Integration
This skill integrates with the following processes:
websocket-server.js - WebSocket server implementation
websocket-client.js - WebSocket client implementation
realtime-messaging-system.js - Real-time messaging architecture
Output Format
When executing operations, provide structured output:
{
"operation": "test",
"target": "ws://localhost:8080",
"status": "success",
"handshake": {
"protocol": "graphql-ws",
"extensions": ["permessage-deflate"]
},
"metrics": {
"messagesReceived": 1000,
"messagesSent": 1000,
"avgLatencyMs": 2.5,
"compressionRatio": 0.65
},
"compliance": {
"rfc6455": true,
"autobahnPassed": 512
Constraints
- Follow RFC 6455 strictly for interoperability
- Server must not mask frames (clients must)
- Validate close codes (1000-1015, 3000-4999)
- Handle UTF-8 validation for text frames
- Limit concurrent connections per client