Files
webappvue1/src/network/signalr.js
2026-05-27 13:36:35 +08:00

100 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import * as signalR from '@microsoft/signalr'
import * as msgpack from '@microsoft/signalr-protocol-msgpack'
import mitt from 'mitt'
import router from '@/router'
export const emitter = mitt()
let connection = null
// 注册消息处理函数
function registerHandlers(conn) {
conn.on('ReceiveMessage', (group, user, message) => {
emitter.emit('ReceiveMessage', { group, user, message })
})
conn.on('OnlineCount', (count) => {
emitter.emit('OnlineCount', count)
})
conn.on('GroupCount', (groupName, count) => {
emitter.emit('GroupCount', { groupName, count })
})
conn.on('SendPrivateMessage', (ResultResponse) => {
emitter.emit('SendPrivateMessage', ResultResponse)
})
conn.on('SendReadReceipt', (messageId) => {
emitter.emit('SendReadReceipt', messageId)
})
// 监听用户状态变化
connection.on("UserStatusChanged", (userId, isOnline) => {
emitter.emit('UserStatusChanged', { userId, isOnline })
})
}
// 初始连接(不带 token
async function createConnection() {
connection = new signalR.HubConnectionBuilder()
.withUrl('http://192.168.1.254:5162/Chat')
.withHubProtocol(new msgpack.MessagePackHubProtocol())
.withAutomaticReconnect()
.build()
registerHandlers(connection)
await connection.start()
emitter.emit('Connected') // 通知页面连接成功
return connection
}
// 刷新 AccessToken
async function RefreshAccessToken() {
const oldRefreshToken = localStorage.getItem('refreshToken')
if (!oldRefreshToken) return
connection.send('RefreshAccessToken', oldRefreshToken)
connection.off('ReceiveNewAccessToken')
connection.on('ReceiveNewAccessToken', async (newAccessToken, newRefreshToken) => {
localStorage.setItem('accessToken', newAccessToken)
localStorage.setItem('refreshToken', newRefreshToken)
await reconnectWithToken()
})
connection.off('RefreshFailed')
connection.on('RefreshFailed', (message) => {
console.error('刷新失败:', message)
localStorage.removeItem('accessToken')
localStorage.removeItem('refreshToken')
router.push('/')
})
}
// 使用新的 token 重建连接
async function reconnectWithToken() {
const accessToken = localStorage.getItem('accessToken')
if (!accessToken) return
if (connection) {
await connection.stop()
}
connection = new signalR.HubConnectionBuilder()
.withUrl(`http://192.168.1.254:5162/Chat?access_token=${accessToken}`)
.withHubProtocol(new msgpack.MessagePackHubProtocol())
.withAutomaticReconnect()
.build()
registerHandlers(connection)
await connection.start()
emitter.emit('Connected') // 通知页面连接成功
}
// 页面加载时自动执行
;(async () => {
await createConnection()
await RefreshAccessToken() // 尝试刷新 token 并重连
})()
export { connection, reconnectWithToken, createConnection }