【问题标题】:Vue & Sockets: Handling sending messages back and forthVue & Sockets:处理来回发送消息
【发布时间】:2021-03-19 01:14:37
【问题描述】:

我有一个消息系统的简单实现或尝试,只是为了向不同用户显示消息警报。我正在使用https://www.npmjs.com/package/vue-socket.io Vue Socket Io,但它只是一个 socket.io。我正在尝试让客户端订阅已安装的事件。该名称基于他们的用户 ID。问题是我下面的实现无法显示警报。我可以看到挂载中订阅的事件,我可以看到在服务器中发送消息控制台日志,所以我知道它正在被触发,但我没有看到 emit(Chat_.... alert /p>

服务器:

io.on('connection', function(socket) {
    socket.on('sendMessage', function (data) {
       console.log("Sending message to" + data.user);
       socket.emit(`CHAT_${data.user}`, data.msg)
    });
 });

客户:

在客户端,userIDSelf 是作为道具传入的用户 ID。这是用户的登录 ID,在 mounted 中,他们会自动订阅附加用户 ID 的聊天频道,就像自定义频道一样。

mounted() {
    this.sockets.subscribe(`CHAT_${this.userIDSelf}`, (data) => {
         alert(data)
    });
}, 

有一个函数sendMessage 从模板中的 2 个输入(未看到)中获取值。您必须输入要将消息发送给谁的用户 ID,然后输入实际消息的另一个输入。这些被发送到上面列出的后端服务器。

methods: {
  sendMessage() {
        this.$socket.emit('sendMessage', {user:  this.userIDReceiver, msg: this.message})
  },
}

【问题讨论】:

    标签: javascript vue.js vuejs2 socket.io


    【解决方案1】:

    我在这里看到了一个逻辑问题。在您的服务器代码中

    io.on('connection', function(socket) {
      socket.on('sendMessage', function (data) {
        console.log("Sending message to" + data.user);
        socket.emit(`CHAT_${data.user}`, data.msg)
      });
    });
    

    向服务器发出sendMessage 事件的socket(用户123)最终也将是从服务器接收发出的CHAT_456 事件的socket。但是用户 123 socket 只监听 CHAT_123 事件。套接字正在向自己发送消息,但没有收到。


    可能的解决方案

    A - room 方法

    一旦套接字连接到服务器上,就根据它的用户 ID 将其放入 room。这需要在连接期间将用户 ID 发送到服务器,例如带有查询参数。在客户端中,只需在连接字符串中添加一个token 查询参数,例如

    const io = require('socket.io-client');
    const socket = io("https://server-domain.com/?token=" + userid);
    

    并通过服务器端房间中的连接套接字(加入)像

    io.on('connection', function(socket) {
      const userid = socket.handshake.query.token;
      socket.join(userid);
    });
    

    那么你的套接字 sendMessage 会像这样工作

    /* ... server side */
    socket.on('sendMessage', function (data) {
      console.log("Sending message to" + data.user);
      io.to(data.user).emit('chatMessage', data.msg);
    });
    

    B - keep reference to the socket 方法

    在内部每个套接字都有一个socket id。通常这些不会暴露给用户/客户。但是,您确实有一个独特的user id。因此,让我们在服务器端保留一个user id / socket instance - 关系,这样您就可以使用用户 ID 为每个相应用户获取对套接字对象的引用。

    最基本的例子是服务器端的内存存储

    let socketRefs = {};
    io.on('connection', function(socket) {
      const userid = socket.handshake.query.token;
      socketRefs[userid] = socket;
    });
    

    那么您的套接字 sendMessage 将像这样工作

    /* ... server side */
    socket.on('sendMessage', function (data) {
      console.log("Sending message to" + data.user);
      let targetSocket = socketRefs[data.user];
      targetSocket.emit('chatMessage', data.msg);
    });
    

    【讨论】:

    • 感谢帕斯卡! But User 123 socket only listens to CHAT_123 events. The socket is sending itself a message but doesn't receive it.。 -- 不能一个套接字,不管它是什么套接字,发出一个事件,无论谁订阅它,明白吗?正在传入用户 ID,并且套接字正在发送到 CHAT_${USERID} 并且 whoever 订阅了它,会得到......对吗?
    • 这需要在服务器上使用io.emit 而不是socket.emit。如果你使用 socket.emit 它只发射到这个套接字。如果你使用 io 那么它会被发送到默认命名空间中的所有套接字。
    • 啊,有道理,非常感谢您对此的回复以及您回答中的上述详细选项!
    • 在进行试验时,您会很快发现许多其他选项。很高兴我能帮上忙!
    • 如果您不介意,还有一件事。如果我按照您提到的方式将其从 socket.emit 更改为 io.emit('CHAT_${data.userID}', data.msg) ,这是一种“好的”处理方式吗?我注意到你没有提到它是你答案中的两个选项之一,所以这就是为什么我想知道这是否不是一个好方法:)。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2019-11-26
    • 2020-06-08
    • 2019-11-24
    • 2020-07-31
    • 2021-04-27
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多