趣聊WebSocket

2023年 8月 13日 29.2k 0

👏作者简介:大家好,我是爱写博客的嗯哼,爱好Java的小菜坤
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
📝个人博客:敬请期待

前言

相信大家都对HTTP协议比较熟悉,因为它是我们接触最多的一个协议。但Websocket跟它又有什么关系,有什么作用呢?这篇文章我们通过HTTP来引出Webscoket这个协议。

一、关于HTTP

1. HTTP请求

  • OSI七层架构:

在这里插入图片描述

大家都知道,HTTP协议是基于TCP协议开发的一款应用层协议,它主要针对的就是网站的一些请求

  • 请求图:

在这里插入图片描述

像这种可以算的上HTTP最简单的请求了,客户端向服务器请求数据,此时服务器响应数据,根据客户端请求的数据来返回对应的信息,可以进行一些基本的获取信息、请求数据一类的请求。

当然根据REST规范,还有POST请求、PUT请求、HEAD请求,这里就不一一列举了,大家有兴趣可以自己查一下。

因为HTTP这种协议只能客户端发送请求,服务器不能主动发送请求。大家看到这或许会有疑惑,为什么还要要求服务器主动推送呢。

  • 普通请求:

在这里插入图片描述

普通请求结合Ajax代码示例:

setInterval(function() {
  $.get("/to/hong", function(data, status) {
      console.log(data);
  });
}, 10000);

大家看这个图就知道了,此时小明想向小红炫耀一下自家的猫多么厉害(或许这就是孩童的乐趣吧),可是服务器并不能主动推送信息,小红永远也收不到,也就无法看到能后空翻的小猫了。

那么该如何解决这个问题呢?乐于助人的攻城狮想出了办法:可以让客户端频繁的去请求服务器不就行了,只要我请求的频率到一定程度,不就和服务器主动推送没区别了吗。

2. 传统轮询

  • 轮询方式:

在这里插入图片描述

传统轮询请求结合Ajax代码示例:

function poll() {
  setTimeout(function() {
      $.get("/path/to/server", function(data, status) {
          console.log(data);
          // 发起下一次请求
          poll();
      });
  }, 10000);
}

因为HTTP请求是请求响应类型的,所以每次HTTP请求之后都会返回数据,即使没有信息,也会返回一个空值。

这样对于聊天的话就会做很多无用的请求,让服务器遭受“凌迟之痛”,并且消耗大量带宽。

小明也很苦恼,明明就发一个消息,为什么消耗这么多流量呢?刚充的花费就没了。乐于助人的攻城狮肯定不会眼睁睁的看着小明因为约会把自己的金钱全部掏空,于是就做了一个违背祖宗的决定。

3. 长轮询

在上面的传统轮询中,巨量的请求都涌向服务器,占据大量网络资源。那么如何才能改进,避免大量资源的占用呢?

长轮询意味着浏览器只需启动一个HTTP请求,其连接的服务器会“hold”住此次连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的HTTP请求,以此类推。

  • 轮询示例:

在这里插入图片描述

跟上面的短轮询对比,从图片上就感觉到不是那么密密麻麻的了。网络也是如此,减少了大量不必要的请求。

轮询可能在以下3种情况时终止:

  • 有新数据推送 。当服务器向浏览器推送信息后,应该主动结束程序运行从而让连接断开,这样浏览器才能及时收到数据。
  • 没有新数据推送 。应该设定一个最长时限,避免WEB服务器超时(Timeout),若一直没有新信息,服务器应主动向浏览器发送本次轮询无新信息的正常响应,并断开连接,这也被称为“心跳”信息。
  • 网络故障或异常 。由于网络故障等因素造成的请求超时或出错也可能导致轮询的意外中断,此时浏览器将收到错误信息。

这时候小明才长长叹拉口气,终于不会把自己的小金库花光了,还准备跟小红约会的时候用呢。

  • 注意:长轮询和长连接是有区别的。长连接是基于TCP的,在协议上的修改,而长轮询是编程挂起手动修改的

二、关于WebSocket

在上面你会发现,就算是HTTP的长轮询也是基于请求-应答的这种半双工通信模式,虽然可以双向的收发数据,但一个时刻只能一个方向有动作,传输效率低。

最终要的一点就是,它是一种被动的通信模式,服务器只能被动的响应客户端请求,无法主动发送数据。

做人不能总是主动,你越主动就越廉价。当然攻城狮也明白这个道理,为了让小明的爱情更加美好,就开始想办法做一个全双工的通信模型,不用像HTTP一样回合制类型那么客套了。于是,服务器就可以变得更加主动,一旦服务器有新的数据,就可以推送给小明,不需要再轮询了,通讯效率也变高了。

1.WebSocket基础

WebSocket采用了二进制帧结构,语法、语义跟HTTP完全不兼容,但现在的龙头老大还是HTTP,于是就尽量的往HTTP靠拢。

服务发现方面,WebSocket没有使用TCP的”IP地址+端口号",而是沿用了HTTP的URL格式,但开头协议名不是http,而是ws和wss,默认端口也选择了80和443。

ws://www.baidu.com:8080/server

这便是websocket的请求路径,唯一不同的就是协议名

2. WebSocket请求流程

作为一个新星协议,它是如何建立连接的呢

  • 建立连接:

从上面这个图可以看出来,Websocket竟然和HTTP有关系,最上面的是HTTP1.1版本,使用的GET请求,其中请求头一个字段很重要Upgrade,看这个意思大家应该都知道,是升级的意思。

这个请求就是使用HTTP请求向服务器传达一个信息,我要开始转换为WebSocket协议。

如果用啦HTTP请求那肯定会有一个响应,因为HTTP就是请求应答模型的,当然这次也肯定不例外。

  • 连接响应:

上面这个就是服务端产生的应答,告诉客户端,已经转换成功,以后我们就可以用Websocket交流信息了(HTTP:就没人管我的死活吗?T﹏T)

那么websocket是如何工作的呢?

在这里插入图片描述

首先就是上面提到的建立连接,建立连接成功之后,就开始进行全双工通信,这时服务端和客户端就可以自由发送请求了。

websocket聊天示例:
在这里插入图片描述

小明:程序猿太厉害了吧,我以后也要成为一名程序猿

3. Websocket总结

WebSocket 是一种基于 TCP 协议的通信协议,它提供了全双工的实时通信能力,使服务器和
客户端之间可以进行双向的、实时的数据传输。

以下是 WebSocket 的一些重要特点和用法:

  • 双向通信:WebSocket 允许服务器和客户端之间进行双向通信,无需依赖于客户端发起请求。服务器可以主动向客户端推送消息或数据,而不需要等待客户端发送请求。

  • 实时性:WebSocket 提供了低延迟的实时通信能力,适用于需要及时推送数据的场景,如即时聊天、实时消息更新等。

  • 长连接:与传统的 HTTP 请求-响应模式不同,WebSocket 在握手阶段建立连接后,连接会保持打开,双方可以长时间保持通信状态,避免了频繁建立和关闭连接的开销。

  • 二进制支持:WebSocket 不仅可以传输文本数据,还支持传输二进制数据,这使得它能够处理多媒体数据、文件传输等更复杂的场景。

  • 适用于 Web 应用和移动应用:WebSocket 可以被广泛应用于 Web 应用和移动应用中,为实时通信提供了强大的支持。

在使用 WebSocket 进行通信时,开发者可以借助相应的 WebSocket 客户端库或者浏览器提
供的 WebSocket API 来实现与服务器的连接和数据传输。同时,服务器端也需要支持
WebSocket 协议来处理客户端的连接和消息。

三、总结

关于HTTP请求和WebSocket的对比:

  • 连接方式:HTTP 是一种无状态的请求-响应协议,每次请求都需要重新建立连接。而 WebSocket 则是一种全双工通信协议,通过一次握手后,客户端和服务器之间可以保持长时间的连接,实现双向通信。

  • 通信效率:由于 HTTP 协议的特性,每次请求-响应的过程会带来较大的开销。而 WebSocket 的长连接可以减少频繁的握手和头部信息传输,从而提高通信效率,特别适合实时性要求高的场景。

  • 数据格式:HTTP 使用文本形式的请求和响应,通常以 JSON 或 XML 格式进行数据传输。而 WebSocket 可以传输二进制数据,可以更高效地处理多媒体数据或其他复杂的格式。

  • 支持性:WebSocket 是一种相对较新的协议,不是所有的浏览器和服务器都完全支持它。而 HTTP 是通用的协议,几乎所有的浏览器和服务器都能良好支持。

综上所述,WebSocket 相对于 HTTP 具有更低的通信延迟、更高的效率和更强大的功能,特别适用于实时通信、推送和实时更新的场景。但在一些简单的请求-响应交互中,仍然可以使用 HTTP。选择使用哪种协议取决于具体的需求和场景。

结语

每个人都有自己独特的才华和潜能,在这个广袤的世界上,你的存在是有意义的。无论你是谁,你的背景如何,你所处的环境怎样,只要你敢于跨出舒适区,付出努力,追求卓越,你就能够开创属于自己的辉煌。

我们下期见。

每一次努力都是一次进步,即使进展缓慢,也要坚持不懈。

往期文章推荐:

  • 关于redis的读写一致问题
  • springsecurity加入第三方授权认证
  • Java连接mysql常遇时间问题

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论