在节点js中创建私人聊天,并且无法将消息发送到特定的套接字ID

时间:2018-08-15 16:46:17

标签: node.js socket.io

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

服务器端文件:

'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。请帮忙。

1 个答案:

答案 0 :(得分:0)

似乎您在toid对象上没有名为data的键。您可能输入错了。将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
               });

编辑:

您在此答案下方的评论中问了以下问题:

  

套接字ID在之后是否自动更改   用户发送消息时登录还是客户端登录后保持不变?

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

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

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

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

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