WebSocket参考

握手头部

# 客户端升级请求 GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 # 服务端响应 (101 Switching Protocols) HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

JavaScript WebSocket API

const ws = new WebSocket('wss://example.com/socket'); // 连接建立 ws.addEventListener('open', (event) => { ws.send(JSON.stringify({ type: 'subscribe', channel: 'news' })); }); // 接收消息 ws.addEventListener('message', (event) => { const data = JSON.parse(event.data); console.log('消息:', data); }); // 错误处理 ws.addEventListener('error', (event) => { console.error('WebSocket 错误:', event); }); // 连接关闭 ws.addEventListener('close', (event) => { console.log(`关闭: code=${event.code}, reason=${event.reason}`); }); // 发送二进制数据 ws.send(new Uint8Array([1, 2, 3]).buffer); // 主动关闭 ws.close(1000, '正常关闭');

关闭码参考

代码名称描述
1000正常关闭操作成功,连接完成
1001离开服务器关闭或客户端页面跳转
1002协议错误遇到协议级错误
1003不支持的数据收到无法接受的数据类型
1006异常关闭连接异常终止(无关闭帧)
1007无效帧文本消息中含非 UTF-8 数据
1008策略违规消息违反服务器策略
1009消息过大消息体积超出处理限制
1011内部错误服务器遇到意外情况

心跳 / Ping-Pong 模式

function createWebSocket(url) { const ws = new WebSocket(url); let pingInterval; ws.addEventListener('open', () => { pingInterval = setInterval(() => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'ping' })); } }, 30000); // 每 30 秒发送心跳 }); ws.addEventListener('message', (event) => { const msg = JSON.parse(event.data); if (msg.type === 'pong') return; // 处理业务消息 }); ws.addEventListener('close', () => { clearInterval(pingInterval); setTimeout(() => createWebSocket(url), 3000); // 自动重连 }); return ws; }

Go 服务端示例 (gorilla/websocket)

var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true // 开发环境放宽;生产环境校验 Origin }, } func wsHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { return } defer conn.Close() for { messageType, p, err := conn.ReadMessage() if err != nil { break } if err := conn.WriteMessage(messageType, p); err != nil { break } } }

readyState 值

常量含义
0CONNECTINGSocket 已创建,尚未连接
1OPEN连接已打开,可以通信
2CLOSING关闭握手进行中
3CLOSED连接已关闭