WebSocket 作为一个在单个 TCP 连接上提供全双工通信的协议,连接一旦建立,客户端和服务器之间就可以进行无限制的双向数据传输。然而,网络通信环境不是总能保证每条信息都可以准确无误地陈述革命的。有时,由于网络拥塞、线路错误或其他原因,消息可能会丢失。这是就需要对收发的数据包进行确认,确保每次发送的数据都能准确到达接收端,这就是 WebSocket ACK——WebSocket 应答机制。
为何需要 WebSocket ACK?
在 WebSocket 通信中,缺少 ACK(acknowledgment, 确认)机制会引致一系列问题。首先,丢包。由于网络环境的不稳定,可能造成数据包丢失,而且发送方无法知道数据包是否已经送达接收方。其次,消息的重复。由于网络的延迟,使得发送方在没有接收到确认信息时,可能会重复发送数据,造成数据的冗余。第三,消息的排序。在网络环境复杂的情况下,消息可能会乱序到达接收方,这将可能引起接收方处理信息的困扰。
三者缺一,都可能给 WebSocket 通信的可靠性带来影响。因此,WebSocket 需要 ACK 这一机制来保证双方通信的准确性。
WebSocket ACK 的工作原理
如同许多通信协议,WebSocket ACK 的工作原理是基于“握手”的原则,但这不再是建立连接时的握手,而是在传输数据时的握手。每当有一个新的数据包被发送时,都会产生一个应答(ACK),对方在接受任何数据包后都必须发送一个应答。WebSocket ACK 在数据包中插入了一个具有标识的序号,这个序号在应答中会被返回给发送方,通过这种方式,发送方便可知道这个数据包到底是否被接收。
更详细的过程是这样的:
- 发送方首先向接收方发送一个数据包,同时设置一个序列号。这个数据包会包含数据和这个序列号。
- 接收方收到数据包后,会生成一个应答,即 ACK。这个 ACK 中也会包含这个接收到的序列号。
- 发送方在收到应答后,会把应答中的序列号与最初发送的序列号进行比对,如果匹配,就认为这个数据包已经成功地被接收方接收。如果在预定时间内没有收到应答,发送方就假设这个数据包在传输过程中丢失了,然后重新发送这个数据包。
- 接收方在得到重复的数据包时,也会返回一个 ACK,但是会忽略这个重复的数据包。
这样,通过 ACK,通信双方保证了数据包在传输过程中不会丢失,从而大大提高了通信的可靠性。
超时和重传机
制超时和重传在改善 WebSocket ACK 的可靠性方面扮演了非常重要的角色。这一机制的运作方式如下:
- 发送方在通过 WebSocket 发送一个消息时,会另外设置一个“超时”计时器。这个计时器的时间长度将取决于网络环境和数据包的重要性。设置超时计时器的目的在于,如果在设定的超时时间内没有收到接收方的 ACK 消息,那么发送方会判断该消息未被正确接收。
- 如果超时计时器到时间(即“超时”发生),则触发“重传机制”。重传机制会让发送方重新发送原消息。重传机制是为了处理可能发生的数据包丢失。这个过程可能会多次进行,直到收到接收方的 ACK 消息或者达到重传的最大允许次数。
- 在接收到应答(ACK)或者达到最大重传次数后,超时计时器将会停止,等待下一次的消息发送。
- 在整个过程中,接收方也会有自身的处理机制。如果接收到的是重传的消息,接收方可以发现这是一个重复的消息。它将向发送方返回 ACK,但不会再次处理这个重复的消息。
通过这样的超时和重传机制,WebSocket 连接可以在面对网络不稳定、数据包丢失等情况时,仍然保证数据的可靠传输。这不仅提升了用户体验,也显著减少了因数据丢失引起的问题。
顺序保证及其它特性
除了保证数据可靠传输外,WebSocket ACK 还有一些其他的特性。如顺序保证,通过序列号和确认序列号,可以确保数据以发送方的顺序呈现给接收方;流量控制,通过滑动窗口机制,可以根据网络状况动态地调整发送速度等等。
在 Apifox 中调试 WebSocket
如果你要调试 WebSocket 接口,并确保你的应用程序能够正常工作。这时,一个强大的接口测试工具就会派上用场。
Apifox 是一个比 Postman 更强大的接口测试工具,Apifox = Postman + Swagger + Mock + JMeter。它支持调试 http(s)、WebSocket、Socket、gRPC、Dubbo 等多种协议的接口,这使得它成为了一个非常全面的接口测试工具,所以强烈推荐去下载体验!
首先在 Apifox 中新建一个 HTTP 项目,然后在项目中添加 WebSocket 接口。
接着输入 WebSocket 的服务端 URL,例如:ws://localhost:3000
,然后保存并填写接口名称,然后确定即可。
点击“Message 选项”然后写入“你好啊,我是 Apifox”,然后点击发送,你会看到服务端和其它客户端都接收到了信息,非常方便,快去试试吧!
以下用 Node.js 写的 WebSocket 服务端和客户端均收到了消息。
总结
WebSocket ACK 是 WebSocket 为提高通信的可靠性而设计的重要组成部分,它通过 ACK 确认、超时和重传等机制确保数据的准确无误地传输,并通过顺序保证、流量控制等特性提高了 WebSocket 通信的效率。但值得注意的是,ACK 机制并非万能的,它也会因为网络环境的突变、超时设置过短或 ACK 丢失等原因导致通信的可靠性降低。
参考链接
学习更多: