API接口每次调用都要走一个完整的握手流程,服务端不能通过API主动向前端客户端发送信息; 针对频繁轮询的情况比较消耗资源;
WebSocket只需建立一次连接,并保持长连接状态,客户端服务端可双向通信,通信简单快捷,资源消耗小。
WebSocket通常用于即时通讯方面的需求。
每个页面可以单独创建WebSocket连接,但是没有必要去做重复操作,所以先把牌坊立好:咱要全局使用
WebSocket服务端后续写篇文章讲一下;
1、根目录创建 /js_sdk/websocket.js :
//websocket.js
import Vue from 'vue'
// 1、用于保存WebSocket 实例对象
export const WebSocketHandle = undefined
// 2、外部根据具体登录地址实例化WebSocket 然后回传保存WebSocket
export const WebsocketINI = function(websocketinstance) {
this.WebSocketHandle = websocketinstance
this.WebSocketHandle.onmessage = OnMessage
}
// 3、为实例化的WebSocket绑定消息接收事件:同时用于回调外部各个vue页面绑定的消息事件
// 主要使用WebSocket.WebSocketOnMsgEvent_CallBack才能访问 this.WebSocketOnMsgEvent_CallBack 无法访问很诡异
const OnMessage = function(msg) {
// 1、消息打印
// console.log('收到消息:', msg)
// 2、如果外部回调函数未绑定 结束操作
if (!WebSocket.WebSocketOnMsgEvent_CallBack) {
console.log(WebSocket.WebSocketOnMsgEvent_CallBack)
return
}
// 3、调用外部函数
WebSocket.WebSocketOnMsgEvent_CallBack(msg)
}
// 4、全局存放外部页面绑定onmessage消息回调函数:注意使用的是var
export const WebSocketOnMsgEvent_CallBack = undefined
// 5、外部通过此绑定方法 来传入的onmessage消息回调函数
export const WebSocketBandMsgReceivedEvent = function(receiveevent) {
WebSocket.WebSocketOnMsgEvent_CallBack = receiveevent
}
// 6、封装一个直接发送消息的方法:
export const Send = function(msg) {
if (!this.WebSocketHandle || this.WebSocketHandle.readyState !== 1) {
// 未创建连接 或者连接断开 无法发送消息
return
}
this.WebSocketHandle.send(msg)// 发送消息
}
// 7、导出配置
const WebSocket = {
WebSocketHandle,
WebsocketINI,
WebSocketBandMsgReceivedEvent,
Send,
WebSocketOnMsgEvent_CallBack
}
// 8、全局绑定WebSocket
Vue.prototype.$WebSocket = WebSocket
2、项目根目录main.js添加全局引入:
import Vue from 'vue'
import App from './App'
import '@/js_sdk/websocket' // 全局引入 WebSocket 通讯组件
new Vue({
el: '#app',
//..............
render: h => h(App)
})
3、在根目录app.vue 中初始化WebSocket相关登录操作:
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
created() {
// 因为我的页面有缓存机制,用户下次有可能直接打开某个登录后才能访问的页面 比如F5刷新了某个页面 需要重连
// 又比如后端服务器因为什么原因突然中断了一下 也需要重新连接WebSocket
// 每3秒检测一次websocket连接状态 未连接 则尝试连接 尽量保证网站启动的时候 WebSocket都能正常长连接
setInterval(this.WebSocket_StatusCheck, 3000)
},
methods: {
// 1、WebSocket连接状态检测:
WebSocket_StatusCheck() {
if (!this.$WebSocket.WebSocketHandle || this.$WebSocket.WebSocketHandle.readyState !== 1) {
console.log('Websocket连接中断,尝试重新连接:')
this.WebSocketINI()
}
},
// 2、WebSocket初始化:
async WebSocketINI() {
// 1、浏览器是否支持WebSocket检测
if (!('WebSocket' in window)) {
console.log('您的浏览器不支持WebSocket!')
return
}
// 2、从后台提取WebScoket服务器连接地址:根据自己业务接口获取 或者直接跳过 下面直接写死
const tmpResource = await this.$Api.Resource.Get('OtherSets_WebSocket_Address').then(res => {
return res
})
const tmpWebsocketSrverAddress = tmpResource.value//可以直接赋值如:ws://127.0.0.1:1234
// 3、创建Websocket连接
const tmpWebsocket = new WebSocket(tmpWebsocketSrverAddress)
// 4、全局保存WebSocket操作句柄:main.js 全局引用
this.$WebSocket.WebsocketINI(tmpWebsocket)
// 5、WebSocket连接成功提示
tmpWebsocket.onopen = function(e) {
console.log('webcoket连接成功')
}
//6、连接失败提示
tmpWebsocket.onclose = function(e) {
console.log('webcoket连接关闭:', e)
}
}
}
}
</script>
<style lang="scss"></style>
3、在需要使用WebSocket的vue页面中调用WebSocket向后端发送消息:
//test.vue
Btn_Test_Click() {
//发送消息
this.$WebSocket.WebSocketHandle.send('曾经沧海难为水,除却浓妆皆是鬼!')
this.$WebSocket.Send('悟已往之不谏,杀鸡取卵扯蛋!')
}
4、如果页面需要接收消息回调:
created() {
this.$WebSocket.WebSocketBandMsgReceivedEvent(this.WebSocket_OnMesage) // 绑定消息回调事件
},
method:{
WebSocket_OnMesage(msg) {//实际消息回调事件
console.log('收到服务器消息:', msg.data)
}
}
封装测试弄了大半天,写篇文章再总结一下,一天就这么过去了;
讲道理2020年春节前后14天家也没回,留在宁波哪儿也没去,一个人吃着泡面没日没夜的赶项目,真心好累;
不过核心功能封装好了好了,用起来是真的很舒服,很开心;
有帮助小伙伴们记得点个赞鼓励一下哟!