uniapp使用socketio刷新后socketId失效的问题

  • 服务端

    // 使用express框架搭建服务器
    const express = require('express');
    const app = express();
    const server = require('http').createServer(app);
    
    const port = 3001;                      // 端口号
    
    // socket.io
    const io = require('socket.io').listen(server);
    const { detail } = require('./socket');
    // socket.io
    io.on("connection", socket => {
        console.log('重新连接')
        detail(io, socket)
    });
    
    // 监听端口
    server.listen(port, ()=>{
        console.log("开启服务!");
    });
    
    module.exports = app
    
    • socket.js

      const userSocket = require('../models/userSocketModel');
      const users = {};
      
      exports.detail = (io,socket) => {
          // 注册socketid
          socket.on('login', async (id) => {
              socket.name = id;
              users[id] = socket.id;
          });
      
          // 用户一对一消息发送
          socket.on('privateChat', async (msg)=>{
              let {message, type, toId, sendId} = msg;
              // 将消息发送出去
              console.log(users);
              io.to(users[toId]).emit('updateChat', message);
          });
      
          // 用户离开
          socket.on('disconnecting',()=>{
              if(users.hasOwnProperty(socket.name)){
                  delete users[socket.name];
                  console.log("用户离开")
              }
          })
      }
      
  • 客户端

    import Vue from 'vue'
    import App from './App'
    
    // 引入socket
    import io from './js_sdk/socket-io/weapp.socket.io.js'
    
    Vue.config.productionTip = false
    
    // 建立连接
    Vue.prototype.socket = io('http://192.168.43.252:3001');
    
    App.mpType = 'app'
    
    const app = new Vue({
        ...App,
    	store
    })
    app.$mount()
    
  • 登录login.vue

    • 登录时触发login事件,注册socketId
    loginSubmit(){
        const {data:res} = await this.$axios.post('/login',params);
        if(res.status == 200){
            // 获取token
            let token = res.token;
            // 解密token
    		const decodeToken = jwt_decode(token);
            // 将当前登录用户id传给后端
            this.socket.emit('login',decodeToken.id);
        }
    }
    
前提
  • 我们需要知道,每次服务器重启socket会断开连接,重新连接后会生成一个新的socketId
  • 按照上面的代码,前后端启动并且登录以后,users里就会存储一个以用户id为键,socketId为值的内容,后面可以通过users[id]拿到对应的socketId进行一对一私聊
问题
  • 在我们刷新页面的时候,socket就会断开重连,按照上面的代码来执行,页面刷新后,打印users发现users是为空的
  • users为空获取不到socketId自然就没办法进行私聊
  • 回到生成socketId的那步,是通过登录时触发this.socket.emit('login',decodeToken.id);来生成socketId
  • 问题就在这,每次刷新页面并没有退出登录,所以this.socket.emit('login')只有在登录的时候才执行了,然而每次刷新socket断开重连都需要获得新的socketId
解决办法
  • this.socket.emit('login',decodeToken.id);这步操作放到别的页面,每次刷新都会加载的页面,比如就放在聊天页面
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值