WebSocket API
https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket/WebSocket
const ws = new WebSocket("地址"); // 创建websocket连接,浏览器自动握手
// 事件:握手完成后触发
ws.onopen = function () {
console.log('连接到了服务器');
};
// 事件:收到服务器消息后触发
ws.onmessage = function (e) {
console.log(e.data); // e.data:服务器发送的消息
};
// 事件:连接关闭后触发
ws.onclose = function () {
console.log('连接关闭了');
};
// 发送消息到服务器
ws.send(消息);
// 连接状态:0-正在连接中 1-已连接 2-正在关闭中 3-已关闭
ws.readyState
Socket.io
原生的接口虽然简单,但是在实际应用中会造成很多麻烦
比如一个页面,既有K线,也有实时聊天,于是:
上图是一段时间中服务器给客户端推送的数据,你能区分这些数据都是什么意思吗?
这就是问题所在:连接双方可以在任何时候发送任何类型的数据,另一方必须要清楚这个数据的含义是什么
回忆HTTP是如何处理这个问题的
你会如何解决这个问题
虽然我们可以自行解决这些问题,但毕竟麻烦
Socket.io帮助我们解决了这些问题,它把消息放到不同的事件中,通过监听和触发事件来实现对不同消息的处理
客户端和服务器双方事先约定好不同的事件,事件由谁监听,由谁触发,就可以把各种消息进行有序管理了
注意,Socket.io为了实现这些要求,对消息格式进行了特殊处理,因此如果一方要使用Socket.io,双方必须都使用
在客户端,使用Socket.io是非常简单的
参见:https://socket.io/docs/v4/client-installation/
在约定事件名时要注意,Socket.io有一些预定义的事件名,比如message、connect等
为了避免冲突,建议自定义事件名使用一个特殊的前缀,比如
$
除此之外,Socket.io对低版本浏览器还进行了兼容处理
如果浏览器不支持WebSocket,Socket.io将使用长轮询(long polling)处理
另外,Socket.io还支持使用命名空间来进一步隔离业务,要了解这些高级功能,以及Socket.io的更多API,请参阅其官方文档
接口文档
测试接口
连接地址:ws://localhost:9527
服务器消息:
- 服务器每隔3秒钟会发送一个消息给客户端
- 每次收到客户端的消息后,服务器会回应一个消息
聊天室接口
连接地址:ws://localhost:9528
服务器触发的事件/客户端需要监听的事件:
事件名 | 触发时机 | 传递的消息 | 传递消息示例 |
---|---|---|---|
$updateUser | 有新用户进入 有老用户退出 自己进入 | 当前聊天室的用户数组 | ['张三', '李四'] |
$name | 自己进入 | 分配的用户名称 | "张三" |
$history | 自己进入 | 历史聊天记录 | [{ name:"张三", content:"你好", date: 1635484786373 }] |
$message | 其他人发送消息 | 消息对象 | { name:"张三", content:"你好", date: 1635484786373 } |
客户端触发的事件/服务器需要监听的事件:
事件名 | 触发时机 | 传递的消息 | 传递消息示例 |
---|---|---|---|
$message | 发送聊天消息 | 消息字符串 | "你好!" |