chat-pc/src/connect.ts

184 lines
4.1 KiB
TypeScript
Raw Normal View History

2024-12-24 08:14:21 +00:00
import { h } from 'vue'
import { NAvatar } from 'naive-ui'
import { useTalkStore, useUserStore, useDialogueStore } from '@/store'
import { notifyIcon } from '@/constant/default'
import WsSocket from './plugins/ws-socket'
import EventTalk from './event/talk'
import EventKeyboard from './event/keyboard'
import EventLogin from './event/login'
import EventRevoke from './event/revoke'
import { getAccessToken, isLoggedIn } from './utils/auth'
const urlCallback = () => {
if (!isLoggedIn()) {
window.location.reload()
}
return `${import.meta.env.VITE_SOCKET_API}/wss/default.io?token=${getAccessToken()}`
}
class Connect {
private conn: WsSocket
constructor() {
this.conn = new WsSocket(urlCallback, {
onError: (evt: any) => {
console.log('Websocket 连接失败回调方法', evt)
},
// Websocket 连接成功回调方法
onOpen: () => {
// 更新 WebSocket 连接状态
useUserStore().updateSocketStatus(true)
useTalkStore().loadTalkList()
},
// Websocket 断开连接回调方法
onClose: () => {
// 更新 WebSocket 连接状态
useUserStore().updateSocketStatus(false)
}
})
this.bindEvents()
}
/**
*
*/
connect() {
this.conn.connection()
}
/**
*
*/
disconnect() {
this.conn.close()
}
/**
*
* @returns WebSocket
*/
isConnect() {
if (!this.conn.connect) return false
return this.conn.connect.readyState === 1
}
/**
*
* @param event
* @param data
*/
emit(event: string, data: any) {
this.conn.emit(event, data)
}
/**
*
*/
bindEvents() {
this.onPing()
this.onPong()
this.onImMessage()
this.onImMessageRead()
this.onImContactStatus()
this.onImMessageRevoke()
this.onImMessageKeyboard()
}
onPing() {
this.conn.on('ping', () => this.emit('pong', ''))
}
onPong() {
this.conn.on('pong', () => {})
}
onImMessage() {
this.conn.on('im.message', (data: any) => new EventTalk(data))
}
onImMessageRead() {
this.conn.on('im.message.read', (data: any) => {
const dialogueStore = useDialogueStore()
if (dialogueStore.index_name !== `1_${data.sender_id}`) {
return
}
const { msg_ids = [] } = data
for (const msgid of msg_ids) {
dialogueStore.updateDialogueRecord({ msg_id: msgid, is_read: 1 })
}
})
}
onImContactStatus() {
// 好友在线状态事件
this.conn.on('im.contact.status', (data: any) => new EventLogin(data))
}
onImMessageKeyboard() {
// 好友键盘输入事件
this.conn.on('im.message.keyboard', (data: any) => new EventKeyboard(data))
}
// 即将废弃
onImMessageRevoke() {
// 消息撤回事件
this.conn.on('im.message.revoke', (data: any) => new EventRevoke(data))
}
onImContactApply() {
// 好友申请事件
this.conn.on('im.contact.apply', (data: any) => {
window['$notification'].create({
title: '好友申请通知',
content: data.remark,
description: `申请人: ${data.friend.nickname}`,
meta: data.friend.created_at,
avatar: () =>
h(NAvatar, {
size: 'small',
round: true,
src: notifyIcon,
style: 'background-color:#fff;'
}),
duration: 3000
})
useUserStore().isContactApply = true
})
}
onImGroupApply() {
// 群申请消息
this.conn.on('im.group.apply', () => {
window['$notification'].create({
title: '入群申请通知',
content: '有新的入群申请,请注意查收',
avatar: () =>
h(NAvatar, {
size: 'small',
round: true,
src: notifyIcon,
style: 'background-color:#fff;'
}),
duration: 30000
})
useUserStore().isGroupApply = true
})
}
onEventError() {
this.conn.on('event_error', (data: any) => {
window['$message'] && window['$message'].error(JSON.stringify(data))
})
}
}
// 导出单例
export default new Connect()