使用 vue-3-socket.io 插件以及node.js实现实时聊天(2)

上一篇文章介绍如何实现群聊和各种配置,这章是在上一篇的代码基础上介绍如何实现私聊功能,接下来我们先更新一下上篇文章的代码

服务端

① 在这里,我们添加一个监听登录的方法来获取客户端发送的 userId,以及获取对应的 socketId,并且push到数组中存储,用于我们后续查询;

注意:socketId 是不固定的,只是当前客户端在这个会话期间发送消息 socket.io 生成对应的 socketId,即某用户当前登录生产的 socketId 和下次登录生成的 socketId 是不一致的。

② 再添加一个 socket 实例对象监听的一个 disconnect 函数,旨在某个客户端断开连接时触发的事件,所以我们可以做类似退出登录的处理,将数组中对应的用户信息过滤。

io.on("connection", (socket) => {
  // 自定义一个登录方法,用于获取用户的id和socketId,用户id用于后续查询socketId,而socketId就是实现私聊功能的核心
  socket.on("login", ({ userId }) => {
    // 此处我们接收一个对象,解构里面客户端传来的userId,并且将其push到用户信息列表中,用于我们在私聊方法中查询socketId
    userList.push({
      userId, // 用户id
      socketId: socket.id, // 对应的socketId
    });

    console.log(userList);
  });

  // 自定义一个chat监听方法,当客户端发布到这个方法时,我们可以获取到发布的消息
  socket.on("chat", (msg) => {
    // 稍后将添加私聊的代码逻辑
  });

  // socket实例对象会监听一个特殊函数,关闭连接的函数disconnect,当用户断开链接,则将其信息于数组中删除
  socket.on("disconnect", () => {
    userList = userList.filter((i) => i.socketId != socket.id);
    console.log(userList);
  });
});

客户端

在客户端,我们要在登录页面,或者根据你实际的开发情况,在某个页面的调用服务端的登录方法,并且传 userId、time 等其他信息。

代码如下:

export default {
  data() {
    let msg = "";

    return { msg };
  },
  methods: {
    // 发布消息方法
    send() {
      // 发布到服务端,在服务端我们已经写好了对应的监听方法,只要有消息发布到服务端就会被接收到
      this.$socket.emit("chat", {
        userId: "",
        msg: this.msg,
      });

      // 清空输入框
      this.msg = "";
    },
  },
  // socket内置的钩子,用来监听服务端发布的方法
  sockets: {
    // 在服务端自定义的发布方法
    privateChatMessage(msg) {
      console.log(msg);
    },
  },
  mounted() {
    // 服务端的登陆方法,你可以自己定义在哪个页面做这个登录逻辑:userId我则是用时间戳代替,在实际开发中当然还是用用户的userId
    this.$socket.emit("login", { userId: new Date().getTime() });
  },
};

私聊功能逻辑

在服务端,我们定义一个私聊事件,获取客户端发来的userId,查询对应的socketId,具体代码逻辑和注释如下:


  // 自定义一个chat监听方法,当客户端发布到这个方法时,我们可以获取到发布的消息
  socket.on("chat", ({ userId, msg }) => {
    // broadcast: 是指发布到全部客户端但不发布到发消息的那个客户端,即你发送了消息,但是服务端不会返回给你
    // socket.broadcast.emit("advertise", msg);

    // 获取客户端发来的userId,查询对应的socketId
    let index = userList.findIndex((i) => i.userId == userId);

    // 定义私聊事件,核心是使用 socket 实例内置的to()方法,来指定一个socketId,并且发送到对应的客户端
    socket.to(userList[index].socketId).emit("privateChat", msg);
  });
  methods: {
    // 发布消息方法
    send() {
      // 发布到服务端,在服务端我们已经写好了对应的监听方法,只要有消息发布到服务端就会被接收到
      this.$socket.emit("chat", {
        userId: "",
        msg: this.msg,
      });

      // 清空输入框
      this.msg = "";
    },
  },
  // socket内置的钩子,用来监听服务端发布的方法
  sockets: {
    // 在服务端自定义的群聊方法
    advertise(msg) {
      console.log(msg);
    },
    // 在服务端自定义的私聊方法
    privateChat(msg) {
      console.log(msg);
    },
  },

实践一下

先打开三个页面,然后指定一个页面的socketId进行私聊,注意服务端修改了代码需要重启一下

控制台打印三个用户的信息

这里我们取第二个页面的 userId 作为接收方,这里只是写死做测试,实际开发中的代码逻辑由你定义

接下来我们在第一个页面发送消息

结果如下,在第二个页面打印出了消息,而第三个页面则没有打印即没接收到消息

至此,我们的私聊功能已经基本完成,当然,在实际的开发环境中,还需要添加各种模块和功能以及对接后端的聊天数据存储,才是比较完善的聊天系统。

下篇文章会讲到如何在宝塔中部署node项目并让你的代码在生产环境中正常运行,最后会在发布一篇有关群聊的文章,如果有疑惑可以在评论区留言,我每天都会追踪最新动态,如果有帮助就留下你的赞或关注吧

  • 19
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值