100 lines
2.8 KiB
JavaScript
100 lines
2.8 KiB
JavaScript
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 }
|