文档首页> IDC服务> WebSocket:从建立连接到关闭的完整流程

WebSocket:从建立连接到关闭的完整流程

发布时间:2024-09-13 20:00       

WebSocket完整流程详解

WebSocket是一种基于TCP的全双工通信协议,允许客户端和服务器之间建立持久的双向连接,实现实时数据传输。本文将详细介绍WebSocket的完整流程,包括建立连接、数据传输和关闭连接等步骤,并对每个环节进行深入解析。

一、WebSocket连接的建立

1. 客户端发起握手请求

客户端通过HTTP协议向服务器发送握手请求,意图将协议从HTTP升级为WebSocket。在这个请求中,包含了一些特殊的头部信息,以表明希望进行协议升级。

HTTP请求示例:

GET /chat HTTP/1.1
Host: example.com:80
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13

解释:

  • GET /chat HTTP/1.1:请求服务器的 /chat路径,使用HTTP/1.1协议。
  • Host: example.com:80:指定请求的主机名和端口号。
  • Upgrade: websocket:表示希望将协议升级为WebSocket。
  • Connection: Upgrade:表示此次连接请求是一个协议升级请求。
  • Sec-WebSocket-Key:客户端随机生成的Base64编码的密钥,用于安全校验。
  • Sec-WebSocket-Version:WebSocket协议的版本号,当前常用版本为13。

2. 服务器验证并处理协议升级

服务器接收到握手请求后,首先对请求头进行验证,确认请求符合WebSocket协议的要求。如果验证通过,服务器将准备响应以完成协议升级。

服务器需验证的要点:

  • 检查 Upgrade头部是否为 websocket
  • 检查 Connection头部是否包含 Upgrade
  • 验证 Sec-WebSocket-Key是否存在且格式正确。
  • 确认 Sec-WebSocket-Version是否支持。

3. 服务器返回握手响应

服务器生成握手响应,包含必要的头部信息,状态码为 101 Switching Protocols,表示协议升级成功。

HTTP响应示例:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

解释:

  • HTTP/1.1 101 Switching Protocols:状态码101,表示协议切换。
  • Upgrade: websocket:确认升级为WebSocket协议。
  • Connection: Upgrade:确认此次连接为协议升级。
  • Sec-WebSocket-Accept:服务器根据客户端的 Sec-WebSocket-Key计算得到的校验值。

校验值计算过程:

服务器从请求头的 Sec-WebSocket-Key获取密钥,拼接上一个固定的GUID(258EAFA5-E914-47DA-95CA-C5AB0DC85B11),然后通过SHA-1哈希和Base64编码生成 Sec-WebSocket-Accept

代码示例(伪代码):

function generateAcceptValue(secWebSocketKey) {
    const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
    const hash = sha1(secWebSocketKey + GUID);
    const acceptValue = base64Encode(hash);
    return acceptValue;
}

解释:

  • secWebSocketKey:客户端提供的密钥。
  • GUID:固定的GUID字符串。
  • sha1():对拼接后的字符串进行SHA-1哈希计算。
  • base64Encode():将哈希结果进行Base64编码,得到 Sec-WebSocket-Accept

4. 连接建立完成

当客户端接收到服务器的握手响应,并验证 Sec-WebSocket-Accept的值正确后,WebSocket连接正式建立。此时,客户端和服务器之间的TCP连接已从HTTP升级为WebSocket协议,双方可以开始双向通信。

二、数据传输

1. 消息格式

WebSocket的数据帧具有特定的格式,用于传输文本或二进制数据。每个数据帧包含帧头和负载数据。

数据帧基本结构:

  • FIN:1位,表示是否为消息的最后一个分片。
  • Opcode:4位,定义了负载数据的解释方式(如文本数据、二进制数据、关闭连接等)。
  • Mask:1位,表示是否对负载数据进行了掩码处理(客户端发送的消息必须掩码)。
  • Payload Length:7位或7+16位或7+64位,表示负载数据的长度。
  • Masking-Key:32位,当Mask为1时存在,用于解码负载数据。
  • Payload Data:实际传输的数据。

2. 客户端发送消息

客户端可以使用WebSocket的 send()方法发送数据。

示例:

// 在浏览器环境中
const socket = new WebSocket('ws://example.com/chat');

socket.onopen = function() {
    socket.send('Hello, Server!');
};

解释:

  • new WebSocket('ws://example.com/chat'):创建一个指向服务器的WebSocket连接。
  • socket.onopen:当连接建立后,触发 onopen事件。
  • socket.send():通过连接发送字符串 'Hello, Server!'

3. 服务器接收并响应消息

服务器接收到客户端的消息后,可以进行处理并发送响应。

示例(Node.js环境):

const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });

server.on('connection', function(socket) {
    socket.on('message', function(message) {
        console.log('Received from client:', message);
        socket.send('Hello, Client!');
    });
});