为什么有HTTP协议,还要有websocket协议
我们通常打开网页,比如一个购物网站。都是点开商品列表,跳转到网页,就能得到商品详情。
这种由客户端主动请求,服务器响应的方式,也符合大部分网页的功能场景。
但是你有没有发现,在这种情况下,服务器从来不会主动给客户端发送消息?
就像你喜欢的女孩从来不求你一样。
但是现在,你在刷网页的时候,右下角会弹出一个小广告,提示你。
学习,好学,勤奋,这些刻在你DNA里的东西都让人动容。
当你点击它的时候,你会发现。
相貌平平的古一提醒你“道士有9条狗,都是横着走的”。
英模会先生告诉你:“我的兄弟们会来砍我。”
大家都来了,你选了一个角色,进入游戏界面。
创建角色页面
这时候一个小怪物上来了,从远处过来,然后用木棍抽打你。
整个过程中你没有点过一次鼠标。服务器会自动给你连续发送怪物的移动数据和攻击数据。
这...太温暖了。
感动之余,问题来了。
在这种服务器主动向客户端发送消息的情况下,是如何做到的呢?
在真正回答这个问题之前,先说一些相关的知识背景。
其实问题的痛点在于,网页如何在用户什么都不做的情况下接收消息并改变。
这其实是一种伪服务器推送的形式。
其实并不是服务器主动给客户端发送消息,而是客户端一直在偷偷请求服务器,而用户并不知情。
这种方式也有很多场景,最常见的就是扫码登录。
但是,会有两个明显的问题。
继续轮询,看看有没有扫码。
那么问题又来了。有没有更好的解决办法?
可以,而且实施成本还很低。
长轮询
长轮询
比如这是某云网盘做的。所以你会发现扫码,点击手机确认,电脑端的网页会秒级跳转。体验非常好。
改为长轮询。
真是一举两得。
这样一种发起请求,长时间等待服务器响应的机制,就是所谓的长训练轮机制。在我们常用的消息队列RocketMQ中,消费者在获取数据时也使用这种方法。
RocketMQ消费者通过长时间轮询获得数据。
像这样,服务器在用户没有感知的情况下将数据推送到浏览器的技术,就是所谓的服务器推送技术。它还有一个不相干的英文名,彗星科技。大家都听说过就好。
上面提到的两种解决方案,本质上都是客户端主动取数据。
它还可以用于简单的场景,如代码扫描登录。
但如果是网页游戏,游戏通常有大量的数据需要从服务器主动推送到客户端。
这就把我们带到了websocket。
什么是websocket?
我们知道TCP连接的两端。同时,双方可以主动向对方发送数据。这叫做全双工。
为什么?
因此,为了更好地支持这种情况,我们需要另一种基于TCP的新协议。
因此,设计了一种新的应用层协议websocket。
不要被这个名字误导了。虽然名字里有个socket,但其实socket和websocket就像雷峰和雷峰塔一样,和它们的接近程度无关。
websocket在四层网络协议中的地位如何建立websocket连接
连接:upgrade upgrade:websocketSec-web socket-Key:T2 a6 wzlawhgqnqruz 2 yuyg r n
这些头头意味着浏览器要升级协议,升级到websocket协议(升级:websocket)。
同时,取一个随机生成的base64代码,发送给服务器。
Base64转换为新字符串
之后,浏览器还使用相同的公共算法将base64代码转换为另一个字符串。如果该字符串与服务器返回的字符串一致,则验证通过。
比较客户端和服务器生成的字符串。
建立websocket连接。drawiowebsocket捕获包
我们可以用wireshark抓取一个数据包,并实际查看该数据包。
客户端请求升级到websocket
服务器同意升级到websocket协议。
有点像“后门下蛋”。
如上所述,协议升级完成后,两端会以webscoket的数据格式相互通信。
数据包在websocket中称为帧。
让我们看看它的数据格式是什么样的。
Websocket消息格式
里面的领域很多,但我们只需要关注以下几个。
操作码字段:用于标记这是什么类型的数据帧。比如说。
当等于1时,它表示文本类型的数据包。
2等于二进制数据类型字节)
等于8是关闭连接的信号。
Payload字段:它存储我们真正想要传输的数据的长度,以字节为单位。例如,如果要发送的数据是字符串“111”,则其长度为3。
此外,我们可以看到有几个存储有效载荷长度的字段。我们可以使用前7位,也可以使用后7+16位或7+64位。
那么问题来了。
我们知道,在数据层面,每个人都是01二进制流。我怎么知道什么时候应该读7位,什么时候应该读7+16位?
Websocket将使用前7位作为标志位。不管下一个数据有多大,先读取前7位,根据它的值决定是再读取16位还是64位。
如果前7位的值为0~125,则表示有效载荷的全长。只需读前7位。
有效负载长度介于0和125之间。
如果是126。这意味着有效载荷的长度在126和65535之间,然后需要读取另一个16位。16位将包含有效负载的实际长度。
有效负载长度介于126和65535之间。
如果是127。这意味着有效载荷的长度范围ampgt;=65536,然后你需要重新读取64bit。这64位将包含有效载荷的长度。这样可以保存2的64次方字节的数据,转换很多太字节,肯定够用。
有效负载长度大于或等于65536。
有效载荷数据字段:要传输的实际数据存储在这里。知道上面的有效载荷长度后,就可以根据这个值截取相应的数据了。
有没有发现一个小细节?websocket的数据格式也是数据头+有效载荷数据的形式。
消息头一般包含消息体的长度,通过它可以截取真实的消息体。
消息边界长度标志着websocket的使用场景
Websocket完美继承了TCP协议的全双工能力,同时也提供了一个周到的解决包粘滞的方案。它适用于大多数需要服务器和客户端之间频繁交互的场景。比如网页/小程序游戏,网络聊天室,还有一些像舒菲这样的网络协同办公软件。
回到文章开头的问题,在使用websocket协议的网页游戏中,怪物移动攻击玩家的行为是由服务器逻辑生成的,对玩家的伤害等数据需要服务器主动发送给客户端,客户端获取数据后显示相应的效果。
websocket使用场景总结
websocket协议可以考虑用于客户端和服务器之间需要频繁交互的复杂场景,比如网页游戏。
Websocket和socket几乎没有关系,只是调用方式类似。
声明:免责声明:此文内容为本网站转载企业宣传资讯,仅代表作者个人观点,与本网无关。仅供读者参考,并请自行核实相关内容。