liveh5-nuxt/app/plugins/websocket.ts
xingyy 462a2b23a9 feat(i18n): 实现国际化支持并优化 WebSocket 连接
- 移除 App.vue 中的固定语言设置
- 在 i18n.ts 中实现系统语言自动检测和手动设置支持
- 添加语言切换时重新连接 WebSocket 的逻辑
- 在 profile 页面添加语言设置入口
- 优化 WebSocket连接过程,添加 accept-language头
2025-02-27 14:38:03 +08:00

117 lines
3.6 KiB
TypeScript

import {authStore} from "@/stores/auth";
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
const { token } = authStore()
const i18n = useNuxtApp().$i18n
const ws = reactive({
instance: null as WebSocket | null,
isConnected: false,
currentPath: '', // 保存当前连接的路径
currentData: null as Record<string, any> | null, // 保存当前连接的数据
// 修改 connect 方法接收路径和数据对象
connect(path: string, data?: Record<string, any>) {
// 保存当前连接的路径和数据,以便后续重连使用
this.currentPath = path
this.currentData = data || null
if (this.instance?.readyState === WebSocket.OPEN) {
this.instance.close()
}
// 构建查询字符串
const queryString =data
? '?' + Object.entries({
token: token.value,
'accept-language': i18n.locale.value, // 添加当前语言作为 accept-language
...data
})
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&')
: '?' + Object.entries({
token: token.value,
'accept-language': i18n.locale.value // 即使没有其他数据,也添加语言
})
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&')
// 构建完整的 WebSocket URL
const wsUrl = `${config.public.NUXT_PUBLIC_SOCKET_URL}${path}${queryString}`
this.instance = new WebSocket(wsUrl)
this.instance.onopen = () => {
this.isConnected = true
console.log('WebSocket 已连接')
}
this.instance.onclose = () => {
this.isConnected = false
console.log('WebSocket 已断开')
/* this.reconnect(path, data)*/
}
this.instance.onerror = (error) => {
console.error('WebSocket 错误:', error)
}
this.instance.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
this.handleMessage(data)
} catch (error) {
console.error('消息解析错误:', error)
}
}
},
// 更新重连方法以支持数据对象
reconnect(path?: string, data?: Record<string, any>) {
setTimeout(() => {
console.log('尝试重新连接...')
// 如果提供了新的路径和数据,则使用新的;否则使用保存的当前路径和数据
this.connect(path || this.currentPath, data || this.currentData || undefined)
}, 3000)
},
// 使用当前保存的路径和数据重新连接
refreshConnection() {
if (this.currentPath) {
console.log('刷新 WebSocket 连接,使用当前语言:', i18n.locale.value)
this.connect(this.currentPath, this.currentData || undefined)
return true
}
return false // 如果没有当前连接信息,返回 false
},
// 发送消息
send(data: any) {
if (this.instance?.readyState === WebSocket.OPEN) {
this.instance.send(JSON.stringify(data))
} else {
console.warn('WebSocket 未连接,无法发送消息')
}
},
// 关闭连接
disconnect() {
if (this.instance) {
this.instance.close()
this.instance = null
}
},
// 消息处理
handleMessage(data: any) {
// 触发自定义事件,让组件可以监听
window.dispatchEvent(new CustomEvent('ws-message', { detail: data }))
}
})
return {
provide: {
ws
}
}
})