WebSocket 是一种数据通信协议,类似于我们常见的 http 协议。
初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?
答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。http基于请求响应实现。
举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。
轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。
典型的websocket应用场景:
- 即时通讯…客服
- 聊天室 广播
- 点餐
基本流程
建立与服务器的连接
socket技术
可以原生的 new Socket()
可以使用包 socket.io
使用 socket.io 客户端与服务器建立 WebSocket 长连接
- 安装包:
npm i socket.io-client
只安装客户端要使用到的包 - 和服务器进行连接
import io from 'socket.io-client'
// 和服务器建立了链接
const client = io('地址', {
query: {
token: 用户token
},
transports: ['websocket']
})
核心API 和服务器进行通讯
client.on('connect', () => {}) // 当和服务器建立连接成功,这个事件就会触发
client.on('message', () => {}) // 接收到服务器的消息,这个事件就会触发
client.on('disconnect', () => {}) // 和服务器断开链接,就会触发disconnect
// 主动给服务器发送消息
client.emit('message', 值)
// 主动关闭和服务器的链接
client.close()
import io from 'socket.io-client'
// 用于缓存 socket.io 客户端实例
const clientRef = useRef<Socket | null>(null)
useEffect(() => {
// 创建客户端实例
const client = io('URL', {
transports: ['websocket'],
// 在查询字符串参数中传递 token
query: {
token: getToken().token
}
})
// 监听连接成功的事件
client.on('connect', () => {
// 向聊天记录中添加一条消息
setMessageList(messageList => [
...messageList,
{ type: 'robot', text: '我现在恭候着您的提问。' }
])
})
// 监听收到消息的事件
client.on('message', data => {
console.log('>>>>收到 socket.io 消息:', data)
})
// 将客户端实例缓存到 ref 引用中
clientRef.current = client
// 在组件销毁时关闭 socket.io 的连接
return () => {
client.close()
}
}, [])