【问题标题】:Creating private chat in node js and unable to send message to particular socket id在节点 js 中创建私人聊天并且无法将消息发送到特定的套接字 id
【发布时间】:2019-01-22 13:58:29
【问题描述】:

以下是我的服务器端和客户端文件:

服务器端文件:

'use strict';
var model = require('../model/model.js');

class Socket{
    constructor(socket){
        this.io = socket;
        this.users = [];
    }

    socketEvents(){ 
        this.io.on('connection', (socket) => {
            socket.on('username', (data) => {

                this.users.push({
                    id : socket.id,
                    userName : data.username
                });


                let len = this.users.length;
                len--;

                model.addSocketId( data.username,this.users[len].id);

                this.io.emit('userList',this.users,this.users[len].id); 
            });

            socket.on('getMsg', (data) => {
                model.insertMessages({
                        fromUserId: data.fromUserId,
                        toUserId: data.toUserId,
                        message: data.msg
                });
                console.log("socket id is:");
                console.log(data.toid);
                socket.broadcast.to(data.toid).emit('sendMsg',{
                    msg:data.msg,
                    name:data.name
                });

            });

            socket.on('disconnect',()=>{
                for(let i=0; i < this.users.length; i++){
                    if(this.users[i].id === socket.id){
                        this.users.splice(i,1); 
                    }
                }
                this.io.emit('exit',this.users); 
            });
        });
    }

    socketConfig(){
        this.socketEvents();
    }
}
module.exports = Socket;


Below is my Client Side File:

<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
    var socket = io.connect("http://192.168.1.12:3000");

    socket.on('sendMsg', (data) => {
        console.log("send message-list");
        $('#message-list').append("<li class='friend-user'>"+data.msg+"</li>");
    });

    socket.on('userList', (completeUserList,userSocketId) => {
       console.log('userlist function');
       var userList = completeUserList;
    });

    $('document').ready(function(){
       $(document).on('click', "#msg-btn", function (event) {
       var messagePacket = {
            toid: $("#friendSocketId").text(),  //stored in hidden format from db 
            msg: $('#message').val(),
            name: $("#myUserName").text(),
            fromUserId: $("#loginUserId").text(),
            toUserId: $("#friendUserId").text(),
    };
    socket.emit('getMsg',messagePacket);
});


</script>

在此,当用户从前端单击发送按钮时,“getMsg”事件成功发出。 getMsg 函数将接收者套接字 ID 作为消息,并向特定套接字 ID 发出“sendMsg”事件。但是 sendMsg 事件不会将 msg 发送到特定的套接字 id。请帮忙。

【问题讨论】:

  • 请看我编辑的答案。

标签: node.js socket.io


【解决方案1】:

您在 data 对象上似乎没有名为 toid 的键。你可能打错了。将toid 替换为toUserId,它应该可以工作。

由于您将消息发送到另一个套接字而不是房间,因此您可以使用socket.to().emit() 而不是socket.broadcast.to()

来自Socket.IO docs

// a private message to another socket
socket.to(/* another socket id */).emit('hey');

因此,将socket.broadcast.to() 替换为socket.to().emit(),例如:

socket.to(data.toid).emit('sendMsg',{
                   msg:data.msg,
                   name:data.name
               });

编辑:

您在此答案下方的 cmets 中提出了以下问题:

socket id 之后会自动改变吗 用户发送消息时登录还是客户端登录时保持不变?

在执行io.connect() 时为每个客户端创建套接字ID。

在您的代码中,这是脚本文件的第一行。因此,每次加载此脚本时都会创建一个新的套接字 ID。

因此,每次加载包含此脚本的页面时,都会创建一个新的套接字 ID。如果刷新页面,此脚本会再次加载并创建一个新的套接字 ID。

要回答您的问题,只要用户在同一页面上,套接字 id 就会保持不变。因此,当用户发送消息时,它不会更改,除非用户导航到另一个页面或在发送消息后刷新此页面。因此,如果用户注销并登录,此页面会再次加载,因此套接字 id 会更改。

我认为您在用户登录后将套接字 id 存储在数据库中,但是当用户导航到另一个页面或注销并再次登录时没有更新它。因此,当您从服务器发出消息时,您将其发送到用户以前的套接字 id,而不是当前的。

【讨论】:

  • 感谢您的回复,但在 console.log 中,我正在获取 data.toid 值,并且对于该特定用户,它存储在 db 中是正确的。
  • 好的!尝试将socket.broadcast.to().emit() 替换为socket.to().emit()。告诉我进展如何。
  • 使用 socket.to(data.toid).emit() 仍然无法正常工作
  • 好的,只是为了确定一下,您是否将此消息发送给发件人(发送此消息的同一个套接字)?
  • 不,我从 chrome 浏览器上的一个用户和 Firefox 上的第二个用户以及我的手机上的第三个用户登录。我正在尝试将私人消息从 chrome 用户发送给 firefox 用户。当我使用 io.emit 时,它在所有 3 个屏幕上都可见,如果我使用的是 socket.emit,那么它只对发件人可见。如果正在使用 socket.to(data.receiverSocketId).emit() 则不会在任何地方接收。我这里有一个问题,当用户发送消息时,socket id 是在登录后自动更改还是在客户端登录时保持不变。请再次阅读我的两个文件。
猜你喜欢
  • 2016-12-13
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 2016-11-04
  • 2014-07-26
相关资源
最近更新 更多