Skip to content

WebSocket基础知识

实时场景的旧处理方案#

考虑网页中的以下场景:

上述场景有一个共同特点——实时性

这种对实时性有要求的页面,会带来一些问题

比如下面的聊天场景

image-20250405132334026

由于HTTP协议是请求-响应模式,请求必须在前,响应必须在后,这就导致了服务器无法「主动」的把消息告诉客户端。

开发者想了很多办法来解决这一问题

当然终极解决方案自然是WebSocket,但了解过去的一些做法、参观前辈们经历的痛苦还是有益的。

短轮询#

short polling,中文翻译为短轮询,是一种「话痨式」的方式。

客户端每隔一小段时间就向服务器请求一次,询问有没有新消息

实现短轮询是非常简单的,客户端只需要设置一个计时器不断发送请求即可

这种方案的缺陷是非常明显的:

长轮询#

我们的前辈在有限的条件下,充分发挥智慧,来解决短轮询的问题,于是演化为长轮询

长轮询有效的解决了「话痨问题」,让每一次请求和响应都是有意义的

但长轮询仍然存在问题:

WebSocket#

伴随着HTML5出现的WebSocket,从协议上赋予了服务器主动推送消息的能力

image-20250405134734354

从上图可以看出:

虽然优于轮询方案,但WebSocket仍然是有缺点的:

原生API#

https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket/WebSocket

const ws = new WebSocket('websocket服务器地址') // 创建一个 websocket 连接
// 事件:
// 握手完成后会触发
ws.onopen = function () {}
// 收到服务器消息的时候会触发
ws.onmessage = function () {}
// 连接关闭之后会触发
ws.onclose = function () {}
// 方法:
ws.send(消息) // 向 websocket 服务器发送消息
// 属性:
ws.readyState // 连接状态 0-正在连接中 1-已连接 2-正在关闭中 3-已关闭

Socket.io#

官网:https://socket.io/

原生的接口虽然简单,但是在实际应用中会造成很多麻烦

比如一个页面,既有K线,也有实时聊天,于是:

image-20250405133419271

上图是一段时间中服务器给客户端推送的数据,你能区分这些数据都是什么意思吗?

这就是问题所在:连接双方可以在任何时候发送任何类型的数据,另一方必须要清楚这个数据的含义是什么

回忆HTTP是如何处理这个问题的

你会如何解决这个问题

虽然我们可以自行解决这些问题,但毕竟麻烦

Socket.io 帮助我们解决了这些问题,它把消息放到不同的事件中,通过监听和触发事件来实现对不同消息的处理

image-20250405133335456

客户端和服务器双方事先约定好不同的事件(这些事件全部都是自定义事件),事件由谁监听,由谁触发,就可以把各种消息进行有序管理了。


-EOF-