太古封魔录2 C++实现WebSocket功能笔记
更加通用的实现文章看这个就行了: https://blog.csdn.net/qq_39540028/article/details/104493049
以下是我们项目中的内容和补充细节
1. C++需要实现WebSocket功能
太古2总算活下去了,小程序也开始流行起来。要实现小程序端,分一杯羹。由于小程序用到了wss,所以要在这方面提供支持。也就是需要实现websocket和SSL的支持。
首先,我们的网络底层是非常过时的ACE,所以要改动很难,因为有很多不相干的代码在干扰这,而且写法非常不人道。
第二,不适合大规模修改和推倒重做,最后决定在原来的基础上,套了一层WebSocket。客户端使用Unity,是有现成的接口直接调用的。他们在原来的处理后,发包之前直接调了Unity的WebSocket接口。服务端收到后,需要做的是解除这一层WebSocket外衣,然后走原来的流程把数据给解析出来。
第三,SSL的支持,现在想到的是用Nginx来实现转发就可以了,问了一些其他同行,都是这样处理的。
2. WebSocket协议解析
WebSocket实现了客户端与服务器之间的全双工通讯。本质是前端与服务器端建立一条TCP长连接,服务端可以随时向前端推送数据,前端也可以随时向服务端发送数据,实现了两者间双向数据实时传输。在WebSocket出现之前,Web前端只能采用传统轮询和长轮询的方式与服务端通讯,这里不展开讲了。
WebSocket协议的官方文档是RFC6455文件,下面对协议的核心部分做一个讲解,每一部分会列出关键注意点。
协议分为:连接握手和数据传输
2.1 连接握手
2.1.1 客户端握手连接格式如下:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
客户端连接格式下面几个关键点需要注意:
请求行: 请求方法必须是GET, HTTP版本至少是1.1
请求必须含有Host
如果请求来自浏览器客户端, 必须包含Origin
请求必须含有Connection, 其值必须含有"Upgrade"记号
请求必须含有Upgrade, 其值必须含有"websocket"关键字
请求必须含有Sec-Websocket-Version, 其值必须是13
请求必须含有Sec-Websocket-Key, 用于提供基本的防护, 比如无意的连接
2.1.2 服务端收到客户端连接后,回复格式如下:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
响应行: HTTP/1.1 101 Switching Protocols
响应必须含有Upgrade, 其值为"weboscket"
响应必须含有Connection, 其值为"Upgrade"
响应必须含有Sec-Websocket-Accept, 根据请求首部的Sec-Websocket-key计算出来
服务端回复中关键点在于Sec-Websocket-Accept值的计算,具体计算方式如下:
将客户端送来的Sec-Websocket-Key的值和258EAFA5-E914-47DA-95CA-C5AB0DC85B11拼接
258EAFA5-E914-47DA-95CA-C5AB0DC85B11是一个magic key,是RFC6455 Page24页中定义的一个固定值,直接用即可。
通过SHA1计算出摘要, 并转成base64字符串
至此,一来一回,客户端和服务器端已经完成WebSocket 握手,连接建立,下一步就是传输数据了。
2.2 数据传输
RFC6455中定义了数据帧的格式,如下:
数据帧的组成结构和其他协议类似,归纳起来:数据头+载荷
WebSocket的数据头长度是可变的,有两个因素影响:
载荷长度的数值大小,Payload length: 占7或7+16或7+64bit,具体看下面详解。
是否有maks key,有的话头部多4个字节
数据帧格式如下:
FIN: 占1bit
0表示不是消息的最后一个分片
1表示是消息的最后一个分片
RSV1, RSV2, RSV3: 各占1bit, 一般情况下全为0, 与Websocket拓展有关, 如果出现非零的值且没有采用WebSocket拓展, 连接出错
Opcode: 占4bit
%x0: 表示本次数据传输采用了数据分片, 当前数据帧为其中一个数据分片
%x1: 表示这是一个文本帧
%x2: 表示这是一个二进制帧
%x3-7: 保留的操作代码, 用于后续定义的非控制帧
%x8: 表示连接断开
%x9: 表示这是一个心跳请求(ping)
%xA: 表示这是一个心跳响应(pong)
%xB-F: 保留的操作代码, 用于后续定义的非控制帧
Mask: 占1bit
0表示不对数据载荷进行掩码异或操作
1表示对数据载荷进行掩码异或操作
Payload length: 占7或7+16或7+64bit
0~125: 数据长度等于该值
126: 后续的2个字节代表一个16位的无符号整数, 值为数据的长度
127: 后续的8个字节代表一个64位的无符号整数, 值为数据的长度
Masking-key: 占0或4bytes
1: 携带了4字节的Masking-key
0: 没有Masking-key
payload data: 载荷数据
贝松君划重点,这里有几个关键点需要注意:
Fin为0,表示一个完整的消息被分片成多个数据帧中传输的,需要一直等待接到Fin为1的数据帧之后,才算收到一个完整的消息。websocketfiles 中的recv_dataframe已经考虑到这一点,因此为此返回给上层的数据都是一个完整的消息包。
只有客户端给服务器端发送数据时才会有masking key,服务器端给客户端发送数据不需要masking key mask掩码
opercode目前只收到过2、8、9。
2是正常的操作,解析后继续按原来的流程走就行了
8是断开连接,收到后服务端也断开连接了
9是WebSocket自带的心跳包,需要把内容给清掉,否则会一直残留在缓冲池中。
太古封魔录2 C++实现WebSocket功能笔记相关推荐
- 神武授权位置服务器,太古封魔录神武获得,神武服务器入口
小编今天给大家带来目前相当热门的修仙游戏,太古封魔录神武服务器这个合集收录了目前玩法非常精彩的修仙类手游,多样化的玩法,精美的游戏画风设定,给玩家带来了极致的游戏享受,支持挂机放置,让你随时随地轻松玩 ...
- 刀剑封魔录多功能修改器 v1.2使用教程
刀剑封魔录是一款新型动作角色扮演类游戏,巧妙的引入了格斗游戏的思想,打破常规地将其与游戏融合一体,在游戏中,玩家可以通过单招.连续技.必杀技与敌人进行格斗,享受搏杀的快乐.而小编此次提供的是刀剑封魔录 ...
- VB.net与VB6 调用Websocket功能的方法--Websocket For VB
概述 Websocket 功能在现今的通信应用开发中越来越普遍,因为Websocket的消息机制,在应用程序进行即时通信时使用非常合适,而且Websocket 是长连接方式,比起以前的http协议,性 ...
- Android实现录屏和截屏功能
Android实现录屏和截屏功能 1. MediaProjectionManager介绍 2.所需权限 3.示例代码 1. MediaProjectionManager介绍 用于获取screen ca ...
- 封魔录退出boss副本自动打开封魔录界面
1.首先在DemonScrollData中写三个方法,分别是设置退出副本时的标志的方法(SetCopyData),包括:副本code,判断是否退出副本的bool值.以及获取退出副本时的标志的方(Get ...
- websocket学习笔记
文章目录 websocket学习笔记 实现的方式 websocket学习笔记 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供 ...
- 全功能笔记软件 Notion v2.0.4 绿色便携版
Notion 是一款「将笔记.知识库和任务管理无缝整合的协作平台」.它具有无限的层级和相互链接的组织弹性,给笔记间的关系提供了足够自由的组织方式:它排版灵活,能够把笔记里的内容按块(Block)进行组 ...
- Django by Example·第二章|Enhancing Your Blog with Advanced Features(为博客系统添加高级功能)@笔记
Django by Example·第二章|Enhancing Your Blog with Advanced Features(为博客系统添加高级功能)@笔记 这本书的结构确实很不错,如果能够坚持看 ...
- 【安信可A9G专题②】A9G在微信公众号上的定位功能笔记分享;
本系列博客学习由 安信可科技 - 官方博客 技术分享,如有疑问请留言或联系邮箱. 1.A9G环境在windows上搭建并编译,串口打印 Hello GPRS 2.A9G在微信公众号上的定位功能笔记分享 ...
最新文章
- 看看40万程序猿怎么评论:对于程序员英语真的重要吗?
- 简介nandflash、norflash、ram、sram、dram、rom、eeprom、flash的区别
- Kong APIGW — v.s. Apache APISIX
- github emoji 表情列表
- Python基础教程:字符串中split与rsplit的方法原理教程
- 贴片铝电容识别及型号_贴片钽电容封装及规格和参数资料
- centos7扩展根分区
- 直播源码中有哪些网络协议需要注意?
- 凯立德地图导航2020年最新版车载_明明有车载导航,为什么很多人还是选择用手机导航?有5个原因...
- Table Dragger - 简单的 JS 拖放排序表格插件
- 三星s7共享网络给linux,三星Galaxy S7WiFi状态下可以共享wifi热点吗【详解】
- DotNetNuke模块开发简介
- java语言与c++语言相比_最突出的特点是_Java 语言与C++语言相比,最突出的特点是( )。_学小易找答案...
- eppp如何导入php文件_PHP如何处理文件权限?(代码示例)
- python抛硬币正面向上概率_Python-计算抛硬币出现连续10次正面朝上的概率的仿真实验...
- pb 哪里找到系统图标_建议收藏的7个高质量图标网站,一网打尽图标素材
- TLSF内存分配器记录
- 第四轮学科评估计算机专业排名,第四轮学科评估
- cuda the launch timed out and was terminated windows11解决方案 关闭TDR
- 超好用笔记软件Typora安装教程
热门文章
- 解决Secure CRT不能显示中文的BUG
- MySQL性能优化,索引优化
- Android 安装应用的两种方式--外部应用安装器安装和静默安装(系统应用)
- 计算机无法共享是怎么回事,打印机无法共享,教您怎么处理打印机无法共享
- Canvas加动画,实现火柴人跳绳效果,Android经典入门教程
- C语言中的getchar()与putchar()详解
- 范特西的伤感空间日志推荐:我在风中颤抖,你却再难回头
- 【鬼脚七经典电商思路】淘宝卖家的竞争力(1)
- 分布式理论:深入浅出Paxos算法
- 程序员壮烈牺牲的阿里巴巴面试,这些面试题带回来分享给大家