需要使用到的变量
键值对象根据sessionId可以更好的存储不同会话的数据,避免出现会话冲突
let sessionId = ref<number>(0)//会话id
let show = ref([true, false, false])//Chat.vue里聊天,关注,粉丝三组件显示隐藏
let userId = sessionStorage.getItem('userId')//登录用户id
let unreadCountMap = reactive<Record<number, number>>({})//以sessionId为键的未读消息数对象
let checkDelId = reactive<Record<number, boolean>>({})//对应消息id,对应是否删除
let unCheckNum = ref<number>(0)//总未读消息
let socket: any//websocke
let isConnected = ref<boolean>(false)//webSocket是否链接
let sessionList: session[] = reactive([])//会话列表
let wsMessageList: messageL[] = reactive([])//聊天消息列表
let MessageList = reactive<Record<number, messageL[]>>({})//以sessionID为键的消息列表对象
let wsLastMessage = reactive<Record<number, messageL>>({})以sessionID为键的最新消息对象
连接webSocket
正常创建webSocket连接,准备三个方法onopen,onmessage,onclose
监听与后端是否连接,消息,断开
function connect(url: string) {
socket = new WebSocket(url)
//连接成功设置已连接
socket.onopen = () => {
// alert('连接成功')
isConnected.value = true
}
// 发送消息,接收消息都会触发
socket.onmessage = async (event: any) => {
}
socket.onclose = (error: any) => {
Cookies.remove('checkLian')
// alert(error)
isConnected.value = false
}
解析onmessage监听代码
由于后端会将所有用户发送的消息包括自己的消息都会将消息数据返回,触发onmessage,
首先:接收赋值最新的消息数据,获取当前页面的sessionId,将当前会话的未读消息数置为零
第二:对最新接收到的消息进行判断是否是当前会话发送的消息,如果不是则增加对应会话的未读消息数
第三:根据最新消息的sessionId,将该消息添加到对应的消息列表键值对象
最后:更新消息列表,根据时间顺序排列
// 发送消息,接收消息都会触发
socket.onmessage = async (event: any) => {
console.log('更新前的消息列表' + JSON.stringify(wsMessageList));
const newMessage = JSON.parse(event.data)
console.log(newMessage.sessionId);
// 确保wsLastMessage[newMessage.sessionId]存在
if (!wsLastMessage[newMessage.sessionId]) {
wsLastMessage[newMessage.sessionId] = { ...newMessage }
} else {
// 更新最后一条消息
Object.assign(wsLastMessage[newMessage.sessionId], newMessage)
}
console.log('获取到的sessioniD'+sessionId.value);
if (sessionId.value == newMessage.sessionId) {
await axios({
url: '/api/message/setUncheckNumZero',
method: 'post',
params: {
sessionId: sessionId.value
}
})
}
// 如果是用户自己发的消息总未读消息数不会++
if (newMessage.speaker.id != Number(userId)&&sessionId.value != newMessage.sessionId) {
unCheckNum.value++
console.log(newMessage.speaker.id + ':' + Number(userId));
// 正确更新未读计数:如果不存在则初始化为1,存在则+1
if (unreadCountMap[newMessage.sessionId] === undefined) {
unreadCountMap[newMessage.sessionId] = 1
} else {
unreadCountMap[newMessage.sessionId]++
}
}
// 最新消息为否删除勾选
if (wsLastMessage[newMessage.sessionId]) {
checkDelId[wsLastMessage[newMessage.sessionId].id] = false
}
// 将新消息添加到消息列表(创建新对象避免引用问题)
// wsMessageList.push({ ...newMessage })
// 确保MessageList[newMessage.sessionId]存在
if (!MessageList[newMessage.sessionId]) {
MessageList[newMessage.sessionId] = []
}
if (wsLastMessage[newMessage.sessionId]) {
MessageList[newMessage.sessionId].push({ ...wsLastMessage[newMessage.sessionId] })
}
console.log('最新的消息列表' + JSON.stringify(wsMessageList));
// console.log('获取到的最新消息' + JSON.stringify(lastMessage));
const sessionListAxios = await axios({
url: '/api/session/getSessionList',
})
// 清空并重新设置会话列表,确保响应式更新
sessionList.length = 0
sessionListAxios.data.data.forEach((session: any) => {
sessionList.push({ ...session })
})
}
主动断开webSocket
调用close(),主动辊断开
// 断开webSocket
function disconnect() {
Cookies.remove('checkLian')
if (socket) {
console.log('你有断开吗');
socket.close()
socket = null
isConnected.value = false
}
}
发送消息
// 发送信息
function sendMessage(message: MessageDTO) {
console.log('发送消息' + message);
if (socket && isConnected) {
socket.send(JSON.stringify(message))
}
}
导出需要用到的方法和变量
return {
sessionId,
wsLastMessage,
MessageList,
show,
checkDelId,
unreadCountMap,
unCheckNum,
wsMessageList,
lastMessage,
message,
isConnected,
sessionList,
connect,
disconnect,
sendMessage,
clearCheckDelId,
}
2246

被折叠的 条评论
为什么被折叠?



