前言
好久没有写文章了哇,哈哈~
很久之前就关心过聊天室这方面的内容,并且想自己写一个,也是很早就 star 了 node.js 实现聊天室的相关几个库,俗话说:“兵马未动,粮草先行”嘛。
结果就是 2023/11/27 给的 star,2024/4/28 才开始写🤪🤪🤪(不要问我为什么时间记得这么清楚😳😳)
BTW,因为文章比较长,所以我打算分成几篇来讲,不然一篇文章太长,大家也没啥兴趣看
闲话少说,进入正文~
正文
3W 法分析 websocket
What
WebSocket 是一种在 Web 浏览器和服务器之间提供双向通信的协议。它基于 HTTP 协议,在初始握手阶段使用 HTTP 协议建立连接,然后通过升级协议头(Upgrade header)将连接升级到 WebSocket。
Why
- 传统的 HTTP 请求-响应模型是指客户端向服务器发送请求,服务器处理该请求并返回响应,然后连接立即关闭。这种模型通常是单向,没有请求就没有响应。
既然 HTTP 这么常见,大多数前后端通信也是使用 HTTP,那为什么会出现 websocket?
没有需求就没有产品
让我们来举一个例子:
- 一个狂风暴雨的晚上,你正在玩一个 MOBA 类游戏,你盯着好友框暗着的网络女神头像小美发呆,刚开始匹配,突然它亮了!你赶紧取消匹配邀他进入房间(存档1)
- 进入游戏后,你迫不及待的邀请小美开麦,给他报信息,给他回血,对面露头后和他一起抓人,幻想着一些甜蜜...(存档2)
- 结束游戏后,小美的声音突然变成了浑厚的男声,你气急败坏,出去就要拉小美进房间开会...(存档3)
好,如果这个用的是我们熟知的最普通的 HTTP 服务,客户端发请求服务器才会给结果,可能
- 在存档 1 时你就会因为服务端响应消息的时间错过和女神的“甜蜜双排”;
- 在存档 2 时你就会因为和小美聊天说话太快从而使两人交流不对等;
- 在存档 3 时你会好奇为什么会听到男声,想质问小美,却发现他的头像已经暗了下去,你只能怀疑自己幻听...
这时候有人想到那我每隔多久就请求一次服务器,再更新一下客户端行吗?我们熟知的轮询应运而生
轮询: 是一种用于客户端向服务器端定期发送请求以获取最新数据的通信模式。在轮询中,客户端会以固定的时间间隔向服务器发起请求,询问是否有新的数据可用。如果服务器有新数据可用,它将在响应中返回给客户端;如果没有,则服务器会返回一个空响应或者标识当前数据没有更新。
短轮询: 客户端会定期地发送一个HTTP请求到服务器,服务器接收到请求后立即返回响应,如果服务器有新数据可用,它会在响应中将数据返回给客户端;如果没有新数据,服务器会返回一个空响应或者告知客户端数据没有更新,客户端在收到响应后,立即发起下一个HTTP请求,以检查新的数据更新。
长轮询: 客户端发送一个HTTP请求到服务器,服务器不会立即返回响应,而是保持连接打开,直到有新数据可用时才返回响应给客户端。如果服务器有新数据可用,它会在响应中将数据返回给客户端;如果没有新数据,服务器会保持连接打开,直到有新数据为止,然后返回响应给客户端。客户端在收到响应后,立即发起下一个HTTP请求,以继续进行长轮询,从而保持连接打开并等待新的数据。
我勒个豆,确实不错啊,你既然得要发请求才响应,那我一直请求😎😎,但这样明眼人都看得出来,客户是爽了,服务器是遭老罪喽,24小时连轴转
因此, websocket 诞生
WebSocket 允许服务器和客户端之间实时地交换数据,允许在单个 TCP 连接上进行全双工通信。在某些场景下比传统的轮询或长轮询更有效。它可以降低通信的延迟,减少网络流量,并支持实时数据推送
How
这就是我们要讲的重头戏了,请耐心看下去
socket
前提知识
学过计网的同学应该都不陌生,第一节课就应该听到过 OSI 网络模型以及 TCP/IP 协议
什么是协议?
协议就是计算机与计算机之间通过网络通信时,事先达成的一种 “约定”。这种“约定”使不同厂商的设备、不同的CPU以及不同操作系统组成的计算机之间,只要遵循相同的协议就能够实现通信。
为嘛要讲这玩意,恶心我?😱欺负我没学过计网?😡
解释
-
官方的解释一贯抽象,我自己的理解就是它是一个人为创造的不存在的层,以一个可配置的对象沟通了传输层与应用层,我们不用管 tcp/ip 的具体协议实现,直接调用 socket 即可进行互联的不同主机间的进程的通信。(感觉就是调库侠嘛,kuku 调就完事了)
-
在进行典型的 CS socket 时,一般会产生三个套接字
- 服务器监听套接字: 这个套接字用于在服务器端监听传入的连接请求。它处于被动等待状态,等待客户端的连接请求。一旦有新的连接请求到达,服务器监听套接字将接受该连接请求,并创建一个新的服务器端套接字与客户端进行通信。
- 服务器端套接字: 服务器端套接字是在服务器接受连接请求后创建的,用于与客户端进行通信。它负责处理客户端发送过来的数据,并向客户端发送响应。
- 客户端套接字: 客户端套接字是在客户端发起连接请求后创建的,用于与服务器进行通信。它负责发送请求给服务器,并接收服务器发送回来的响应数据。
服务器监听套接字可以更好的实现并发,监听并接受客户端的连接请求,为每个连接请求创建相应的服务器端套接字,最主要还是因为在典型的客户端-服务器通信模型中,服务器需要主动地监听传入的连接请求。
-
在进行网络通信时,Socket包含了进行网络通信所必须的几种信息:
- 连接所使用的的协议。
- 本地主机的IP地址。
- 本地远程的协议端口。
- 远程主机的IP地址。
- 远地进程的协议端口。
-
详细步骤
结语
下次再见~~