赞
踩
WebSocket 是一种在 Web 应用程序中实现全双工通信的协议。它允许客户端和服务器之间建立一个持久的连接,双方可以在这个连接上相互发送数据,而不需要通过传统的 HTTP 请求/响应模式。这使得 WebSocket 特别适用于实时应用,如聊天应用、在线游戏、实时数据推送等。以下是 WebSocket 的工作原理的详细说明。
WebSocket 连接的建立从一个 HTTP 请求开始。客户端通过一个 HTTP 请求(通常称为 "握手" 请求)请求升级协议,从 HTTP 升级到 WebSocket。
客户端请求:
http复制代码
GET /chat HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com
Upgrade: websocket
和 Connection: Upgrade
标头表示客户端请求升级到 WebSocket 协议。Sec-WebSocket-Key
是一个 Base64 编码的随机密钥,用于安全验证。服务器响应:
http复制代码
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat
101 Switching Protocols
表示服务器同意协议升级。Sec-WebSocket-Accept
是服务器基于 Sec-WebSocket-Key
计算的一个值,确保握手请求的合法性。一旦连接建立,客户端和服务器之间的通信使用 WebSocket 帧(frame)。WebSocket 帧有不同的类型,包括文本帧、二进制帧、关闭帧、Ping 帧和 Pong 帧。
每个 WebSocket 帧都有一个固定的头部格式,用于控制帧的类型和传输的负载数据。
WebSocket 连接可以由客户端或服务器任意一方关闭。关闭连接的过程通过发送一个关闭帧来实现,另一方收到关闭帧后会响应一个关闭帧并关闭连接。
http复制代码
// 客户端或服务器发送关闭帧 0x88 0x00
关闭帧的第一个字节 0x88
表示帧的类型为关闭帧,第二个字节 0x00
表示负载长度为 0。
javascript复制代码
// 创建 WebSocket 连接 var socket = new WebSocket("ws://example.com/socket"); // 连接打开事件 socket.onopen = function(event) { console.log("WebSocket is open now."); // 发送数据 socket.send("Hello Server!"); }; // 接收消息事件 socket.onmessage = function(event) { console.log("Received message from server:", event.data); }; // 连接关闭事件 socket.onclose = function(event) { console.log("WebSocket is closed now."); }; // 连接错误事件 socket.onerror = function(error) { console.log("WebSocket error:", error); };
javascript复制代码
const WebSocket = require('ws'); // 创建 WebSocket 服务器 const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', function connection(ws) { console.log('A new client connected'); // 接收消息事件 ws.on('message', function incoming(message) { console.log('Received message:', message); // 发送消息给客户端 ws.send('Hello from server'); }); // 连接关闭事件 ws.on('close', function close() { console.log('Client disconnected'); }); });
WebSocket 帧头部格式如下:
复制代码
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len | Extended payload length | |I|S|S|S| (4) |A| (7) | (16/64) | |N|V|V|V| |S| | (if payload len==126/127) | | |1|2|3| |K| | | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + | Extended payload length continued, if payload len == 127 | + - - - - - - - - - - - - - - - +-------------------------------+ | |Masking-key, if MASK set to 1 | +-------------------------------+-------------------------------+ | Masking-key (continued) | Payload Data | +-------------------------------- - - - - - - - - - - - - - - - + : Payload Data continued ... : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | Payload Data continued ... | +---------------------------------------------------------------+
126
或 127
,则使用扩展的负载长度字段。MASK
设置为 1,则此字段用于解码负载数据。WebSocket 提供了一种在客户端和服务器之间进行实时通信的高效方法。通过一次握手请求,WebSocket 可以建立一个持久的、全双工的通信连接,减少了频繁建立和关闭连接的开销。理解其工作原理和帧格式有助于在应用中更好地使用和调试 WebSocket,从而实现高效的实时通信。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。