当前位置: 首页 > news >正文

11.2.3 固定话题聊天实现

1 Websocket连接实现

CWebSocketConn继承CHttpConn

大体的框图(代码实现时 函数命名有部分差异)

2实现登录历史消息拉取

见int ApiGetRoomHistory(Room &room, MessageBatch &message_batch); 函数的实现。

3 实现客户端发送消息到服务端

见void CWebSocketConn::sendHelloMessage()函数。

4 实现服务端广播消息给客户端

见int CWebSocketConn::handleClientMessage(Json::Value &root)函数。

5 websocket简单参考

WebSocket 协议是一种基于 TCP 的双向通信协议,允许客户端和服务器在单个连接上进行全双工通信。以 下是 WebSocket 协议的完整解析,包括握手、数据帧格式、心跳机制和关闭流程。

5.1. WebSocket 握手(Handshake)

WebSocket 握手是基于 HTTP 协议的,客户端通过发送一个 HTTP 升级请求来建立 WebSocket 连接。

客户端握手请求

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
  • Upgrade: 指定协议为 websocket 。
  • Connection: 值为 Upgrade ,表示请求协议升级。
  • Sec-WebSocket-Key: 客户端随机生成的 Base64 编码字符串,用于服务器验证。
  • Sec-WebSocket-Version: WebSocket 协议版本,通常为 13 。

服务器握手响应

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
  • 101 Switching Protocols: 表示协议切换成功。
  • Sec-WebSocket-Accept: 服务器对客户端 Sec-WebSocket-Key 进行处理后返回的值,计算公式为:
Sec-WebSocket-Accept = base64(sha1(Sec-WebSocket-Key + "258EAFA5-E914-47DA-95CAC5AB0DC85B11"))

5.2. WebSocket 数据帧格式

WebSocket 数据帧是 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 ...                    |
+---------------------------------------------------------------+

字段说明

1. FIN (1 bit): 表示是否是消息的最后一帧。如果为 1 ,则表示是最后一帧。

2. RSV1, RSV2, RSV3 (各 1 bit): 保留字段,必须为 0 ,除非扩展协议定义了非零值。

3. Opcode (4 bits): 定义帧的类型:

  • 0x0 : 连续帧(continuation frame)
  • 0x1 : 文本帧(text frame)
  • 0x2 : 二进制帧(binary frame)
  • 0x8 : 关闭帧(connection close)
  • 0x9 : Ping 帧 0xA : Pong 帧

4. Mask (1 bit): 表示是否对数据进行了掩码处理。客户端发送的数据必须掩码( 1 ),服务器发送的数据不能掩 码( 0 )。

5. Payload Length (7 bits): 数据长度:

  • 如果值为 0-125 ,表示数据长度。
  • 如果值为 126 ,则后续 2 字节表示长度。
  • 如果值为 127 ,则后续 8 字节表示长度。

6. Masking-Key (4 bytes): 如果 Mask 为 1 ,则包含 4 字节的掩码键,用于解码数据。

7. Payload Data: 实际传输的数据。

5.3. WebSocket 心跳机制(Ping/Pong)

WebSocket 通过 Ping 和 Pong 帧实现心跳机制,用于检测连接是否存活。

Ping 帧: 由客户端或服务器发送,用于检测对方是否在线。 Opcode 为 0x9 。

Pong 帧: 作为对 Ping 帧的响应,表示连接正常。 Opcode 为 0xA 。

5.4. WebSocket 关闭连接

WebSocket 通过关闭帧(Close Frame)来优雅地关闭连接。

关闭帧: Opcode 为 0x8 。 可以包含一个关闭状态码和原因(可选)。 状态码示例:\

  • 1000 : 正常关闭。
  • 1001 : 端点离开。
  • 1002 : 协议错误。
  • 1003 : 不支持的数据类型。
  • 1008 (Policy Violation): 策略违反,表示数据或行为违反了某些策略。

5.5. WebSocket 协议流程总结

1. 握手: 客户端发送 HTTP 升级请求。 服务器响应 101 状态码,完成握手。

2. 数据传输: 客户端和服务器通过数据帧(Text/Binary Frame)传输数据。

3. 心跳检测: 通过 Ping/Pong 帧维持连接。

4. 关闭连接: 通过 Close Frame 优雅关闭连接。

5.6. WebSocket 协议示例

客户端发送文本消息

1. 客户端发送数据帧: FIN: 1 Opcode: 0x1 (文本帧) Payload: Hello, Server!

2. 服务器接收并处理消息。

服务器发送 Pong 帧

1. 客户端发送 Ping 帧。 2. 服务器回复 Pong 帧。

关闭连接

1. 客户端发送 Close Frame。 2. 服务器回复 Close Frame,关闭连接。

参考链接:0voice · GitHub

http://www.dtcms.com/a/389036.html

相关文章:

  • CAN(控制器局域网)工业协议教学文档(一)
  • PHP基础-变量与常量(第八天)
  • SQ01,SQ02,SQ03,SE93事务码配置
  • AI提示词Excel 表格提取数据准确度处理
  • DeviceNet 转 EtherNet/IP 实现罗克韦尔 PLC 与库卡机器人在汽车白车身焊接的微秒级数据同步协作案例
  • GPT-5 vs Gemini 2.5 Pro:两大AI旗舰模型深度技术对比
  • 31、GPT核心引擎完整手工构建:从算法原理到工程优化(Generative Pre-trained Transformer)
  • MySQL MHA 完整配置与故障后原主库还原指南
  • 栈-946.验证栈序列-力扣(LeetCode)
  • spring boot3.0整合rabbitmq3.13
  • Scrapy爬虫利器:CrawlSpider详解
  • 从零开始学Flink:数据源
  • GRPO算法复现
  • AI+Flask博客项目实战提示词笔记 20250918
  • 无人设备遥控器之时间戳技术篇
  • 模块四 展望微服务
  • RN 添加 <NavigationContainer>组件报错
  • 深入理解 AVL 树
  • 软考中级习题与解答——第八章_计算机网络(2)
  • FinalShell远程连接CentOS下方文件列表信息不显示且刷新报空指针异常
  • 贪心算法应用:线性规划贪心舍入问题详解
  • 设计模式学习笔记(二)
  • 轻量化录屏插件,MP4输出格式
  • 静态代理 设计模式
  • Salesforce知识点:触发器:自动化业务逻辑的核心工具详解
  • CentOS 8.5部署Zabbix6.0 agent2端
  • 【TestCenter】设置DHCP Option
  • Jenkins 安全清理孤立工作区(workspace)的 Shell 脚本:原理、实现与实战
  • WebDancer论文阅读
  • Node.js、npm 和 npx:前端开发的三剑客