在开发过程中,会遇到这么一个问题,例如:用户修改了某个角色权限,那么就需要给所有有这个角色的人员实时发送通知,这时候就涉及到实时通信的问题了,今天就按照我自己的理解封装一个WebSocket。
首先,在Vue3项目中安装sockjs-client和stompjs:
npm install sockjs-client stompjs
封装hooks
import SockJS from 'sockjs-client/dist/sockjs.min.js'
import Stomp from 'stompjs'
import router from '@/router'
import { useRoute } from 'vue-router'
const route = useRoute()
const isConnected = ref(false)
const socketUrl = ref(url地址) // 线上地址
const timer = ref<any>(null)
export function useWebsocketHook() {
let stompClient: Stomp.Client
if (timer.value) {
clearTimeout(timer.value)
timer.value = null
}
function connectWebSocket() {
//1连接SockJS的endpoint是“endpointWisely”,与后台代码中注册的endpoint要一样。
const socket = new SockJS(socketUrl.value)
//2创建STOMP协议的webSocket客户端
stompClient = Stomp.over(socket)
//3连接webSocket的服务端。
stompClient.connect(
{},
() => {
console.log('连接成功')
isConnected.value = true
//4通过stompClient.subscribe()订阅服务器的目标是'/user/' + userId + '/msg'接收一对一的推送消息,其中userId由服务端传递过来,用于表示唯一的用户,通过此值将消息精确推送给一个用户
stompClient.subscribe(
`/topic/sysMessage/${用户id}`,
(res: any) => {
//后端返回的数据
const msg: any = JSON.parse(res.body)
//前端显示在页面上的提示弹窗
messageFunc(msg.messageContent, time, msg.messageType)
}
)
},
(error) => {
console.log('连接失败: ' + error)
timer.value = setTimeout(() => {
connectWebSocket()
}, 30000)
isConnected.value = false // 更新连接状态
}
)
}
//断开链接
function disconnectWebSocket() {
if (stompClient && stompClient.connected) {
stompClient.disconnect(() => {
isConnected.value = false // 更新连接状态
console.log('断开连接')
})
}
}
//弹窗提示
function messageFunc(content: string, time: string, type: string | number) {
const messageRef = ref<any>()
messageRef.value = ElMessageBox.confirm(content, '提示', {
confirmButtonText: '退出登录',
cancelButtonText: '取消',
type: 'warning',
customClass: 'websocketView-dialog',
})
.then(() => {
userStore
.logout()
.then(() => {
disconnectWebSocket()
})
.then(() => {
console.log('退出')
})
})
.catch(() => {})
}
return {
connectWebSocket,
disconnectWebSocket,
}
}
然后在登录或者退出登录的时候使用:
// 引入自定义hooks
import { useWebsocketHook } from '@/hooks/useWebsocket'
const websocketHook = useWebsocketHook()
//在登录时链接WebSocket
function goHome () {
login(参数)
.then(async (data) => {
//建立链接
websocketHook.connectWebSocket()
}).
.finally(() => {
console.log('error')
})
}
//在退出登录时断开链接
function logout() {
ElMessageBox.confirm('确定退出吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(() => {logout().then(() => {
//断开WebSocket链接
websocketHook.disconnectWebSocket()
}).then(() => {
console.log('退出')
})}).catch(() => {})}
以上就是创建了一个名为useWebsocket
的hook,它接受一个URL和一个回调函数messageFunc,这个回调函数会在收到消息时被调用。connectWebSocket方法用于建立WebSocket连接,而disconnectWebSocket用于关闭连接。