最近一期的项目使用到了websocket,原因当然是因为长连接的特性,可以让网页实时接收到最新数据并更新页面。
区别于http,只能由用户端发送请求,服务端给出响应。
而websocket的特点在于可以主动给用户推送消息,因为二者之间会建立一个消息通道,只要没有断开,可以一直通信
开整!
1.建立连接,发送请求,接收响应
创建和使用都很简单,为了顾及页面刷新断开连接的问题,我们将websocket实例定义在一个全局变量上,这样任何一个页面刷新,都可以通过重新建立连接而恢复。
新建一个websocket.js
const creatWebSocket = () => {
return new Promise((resolve, reject) => {
//由服务端提供一个ws地址↓
const websocketUrl = 'ws://ip:port/test'
window.webSocket = new WebSocket(websocketUrl)
window.webSocket.addEventListener('open', () => {
console.log('连接成功');
//监听接收消息
window.webSocket.onmessage = function(message) {
console.log(message)
}
webSocket.onerror = function() {
reject(false)
}
webSocket.onclose = function() {
webSocket = null
// 清除保活定时器
console.log('检测到连接断开');
}
})
})
}
export default creatWebSocket
通过promise创建,并将结果导出。
其他页面导入使用,可以实现在创建完成后,异步执行其他行为,如登录请求,一定要在连接成功之后再执行。
那么怎样发送请求并接受对应的响应信息呢?
onmessage中怎样把收到的数据返回给请求函数呢?
这里我们使用一个对象requestPromises来存储请求时的回调函数,用于在接收时数据时返回给请求体,代码如下
const sendSock = (data) => {
return new Promise((resolve, reject) => {
if (window.webSocket) {
requestPromises = {
resolve,
reject
}
// 发送请求
window.webSocket.send(data)
} else {
ElMessage({
message: '服务断开连接',
grouping: true,
type: 'error',
})
}
})
}
而在上述的onmessage中,此时可以这样写
window.webSocket.onmessage = function(message) {
if (message.errorCode == 0) {
requestPromise.resolve(decryptedObj);
}else{
//统一处理请求出错提示
}
}
2.页面刷新保持长连接
首先当页面刷新时,websocket连接一定会断开。
因为当浏览器页面刷新时,WebSocket连接会断开,这是因为页面刷新会导致浏览器重新加载页面内容。页面刷新本质上是浏览器重新获取HTML文档并重建页面的所有资源,包括JavaScript文件和其他依赖项。因此,WebSocket连接也会被关闭。
我们可以实现的是,刷新时,在App.vue页面的onBeforeUnmount生命周期中主动关闭连接,在生命周期onBeforeMount重新建立连接,因为任何页面的刷新都会执行这一环节。
onBeforeMount(){
//重新建立websocket连接
}
onBeforeUnmount(() => {
window.webSocket.close()
window.webSocket = null
})
有网友说,Web Worker可以保持长连接不断开,有时间可以研究下。