前后端交互,记录pinia配置webSocket

需要使用到的变量

键值对象根据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,
  }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值