【问题标题】:private messaging with socket.io sends messages to unintended users使用 socket.io 的私人消息发送消息给非预期用户
【发布时间】:2014-10-27 01:01:21
【问题描述】:

一直在尝试使用 node.js 和 socket.io 创建一个聊天应用程序,但已经卡住了一段时间,这就是为什么,我通过单击该人的用户名成功实现了在已连接用户之间发送私人消息你想私下聊天,但我现在面临的问题是,例如,假设聊天应用程序中有 3 个连接的用户(比如joy、grace、shanel),当joy 决定与grace 聊天时,聊天应用程序会处理这个问题很好,但是如果joy在第一次和grace聊天后决定和shanel聊天,joy本来是给shanel的私信最终会被发送到grace,(即grace和shanel都收到这条私信给grace),这就是问题所在一直面对。我的代码在下面,对不起这篇文章,我希望有人能帮助理解我的情况:)

server.js 代码

   var express = require('express');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var usernames={};
var sockets = {};
var names= {};


app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
  res.sendfile('index.html');
});

io.on('connection', function(socket){
  socket.on('send_msg', function(msg){
     console.log('a user connected');
    io.emit('chat message', msg);
    //console.log(msg);

  });

   socket.on('new_user',function(user){
    console.log('new user:'+user);
       names[socket.id] = user;
       socket.nickname= user;
       usernames[socket.nickname] = socket;
        sockets[user]=socket.id;
        socket.emit('update_personal', "you are now online");
        io.emit('update_users',names);

    });

    socket.on('disconnect', function(){
        io.emit('update_personal', usernames[socket.id]+' is now offline');
        //delete usernames[socket.id];
        delete names[socket.id];
         delete usernames[socket.nickname];
         // io.emit('update_users',usernames,usernames[socket.id]);
            io.emit('update_users',names);
          //console.log(usernames+'specific user id'+usernames[user]);
    });

    socket.on('private_msg', function(msg,recipient,sender){

        console.log('you are trying to send '+msg+' to '+recipient+ ' from '+sender);


        var id = sockets[recipient];

        console.log(sockets[recipient]);
      io.to(id).emit('received_p_msg', msg,sender,recipient);

      recipient = '';
      console.log('value in recipient:'+recipient);


    });
});

http.listen(3000, function(){
  console.log('listening on *:3000');

});

client.html

<!doctype html>
<html>
  <head>

    <title>my chat app</title>
    <!------------------
    <style>
    <!-----------
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
      #chat_msg{

      }
    </style><!-------!>

  </head>
  <body>
  <!---username login here----->
  <div id="login">
  <form id="chat_msg">
  <label>Enter Username:</label>
  <input type="text" id="username"/>
  <input type="button" id="join" value="Create Username"/>
  </form>

  </div>
  <div>
  <div id="online_users"><li>List of online users:</li></div>
  </div>

  <!---public room chat begins here----->
  <div id="chat" style="display: none;">

    <ul id="messages"></ul>
    <form action="">
      <input id="msg" autocomplete="off" />
      <button id="send" >Send</button>
    </form>
    </div>

    <!---private chat begins here----->
    <div id="private_chat" style="display: none;">
    <p id="private_user">Private chat with: </p>
    <div id="private_msg"></div>

    <form action="">

      <input id="p_msg" autocomplete="off" />
      <button id="p_send" >Send private msg</button>
    </form>
    </div>
    <script src="/socket.io/socket.io.js"></script>
     <script src="jquery-2.1.0.js"></script>
    <script>
    $(document).ready(function(){

      var socket = io('http://192.168.173.1:3000/');

      $('#chat').hide();
       $('#username').focus();


      $('form').submit(function(e){
        e.preventDefault();
        });

        var username = $('#username').val();


        $('#join').click(function(){
           var username = $('#username').val();
           console.log('entered username '+username);
           if(username !=''){
            socket.emit('new_user', username);
            $('#login').detach();
            $('#chat').show();
            $('#msg').focus();
           }
        });

        $('#send').click(function(){
             socket.emit('send_msg', $('#msg').val());
        $('#msg').val('');

        });


      socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
      });

      socket.on('update_personal', function(status){
        $('#messages').append($('<li>').text(status));
      });

      socket.on('update_users', function(names){
        console.log(names);


        if(true) {

                              $("#online_users").empty();
                $.each(names, function(clientid, name) {
                    $('#online_users').append("<li><a href='#' id='"+name+"' name='"+name+"' class='private'> " + name + "</a></li>");
                });
                   // $('#online_users').html("<li><a href='#' id='"+name+"' name='"+name+"' class='private'> " + name + "</a></li><br/>");


         $('a.private').click(function(){
      $('#private_chat').hide();

      $('#private_chat').show();
      var sender = username;


    var recipient = $(this).attr('name');


      console.log('name gotten is:'+recipient);
      $('p#private_user').html('private chat with :'+ recipient);

        $('#p_send').click(function(){
            msg = $('#p_msg').val();
            if(msg!=''){
                recipient=recipient;
             socket.emit('private_msg', msg,recipient,sender); // msg from sender, username of the sender, username of recipient
       $('#p_msg').val('');
       }else{$('#p_msg').val('please enter a valid msg');}
        });
      });

                    }
      });
      socket.on('received_p_msg', function(msg,sender,recipient){
         $('#private_chat').show();

         console.log('received privatemsg: '+msg);
         $('#private_user').html('privatE chat with : '+ sender);
        $('#private_msg').append($('<div>').html(msg+'</div>'));

        //to continue chat after receiving initial private msg
        $('#p_send').click(function(){
            msg = $('#p_msg').val();
               if(msg!=''){
             socket.emit('private_msg', msg,sender,recipient); // msg from sender, username of the sender, username of recipient
        $('#p_msg').val('');
       }else{$('#p_msg').val('please enter a valid msg');}

        $('#p_msg').val('');

        });

       });

      socket.on("disconnect", function(){
            $("#msgs").append("The server is not available");

      });



      });
    </script>
  </body>
</html>

【问题讨论】:

  • 检查 socket.io 文档中的房间和命名空间,应该可以解决您的问题
  • 感谢您的回复,但我觉得您的回复有点含糊,因为我对 socket.io 和 node 还是有点陌生​​,我真的很感激,如果您能解释一下,非常感谢!:)
  • 对不起,我现在不能,我稍后会解释得更好。这是online demosource code。希望对你有帮助
  • 好的,感谢您的帮助,我会检查这些链接,谢谢
  • 我检查了链接,它们更多地是关于公共聊天的,我担心我在私人聊天中遇到的问题(如上所述)。我会耐心等待你有空更好地解释如何解决我的这个私聊问题,到此为止,再次感谢。

标签: node.js sockets


【解决方案1】:

关于您的问题,我注意到如果您想打开多个私人聊天,则不能,因为只有一个 username,因此无法选择多个客户来发送聊天消息。例如,您需要将username 变量扩展为usernames 的数组。

我在您的 client.html 文件中发现了一个可能的错误,其中 username 取自 $("#username").val() 但它是 undefined。如果我正确理解了您的代码(3 行不同的行),我建议您进行此修复:

// the line below differs
var username = null;
var socket = io('http://192.168.173.1:3000/');

$('#chat').hide();
$('#username').focus();

$('form').submit(function(e){
    e.preventDefault();
});

// the line below differs
//var username = $('#username').val();

$('#join').click(function{
    // the line below differs
    username = $('#username').val();
    console.log('entered username '+username);
    if(username !=''){
        socket.emit('new_user', username);
        $('#login').detach();
        $('#chat').show();
        $('#msg').focus();
   }
});

【讨论】:

  • 感谢您的快速响应,我修复了您在客户端指出的错误,之前的代码仍然有效,因为我再次重新声明了用户名变量(糟糕的编码道德)。关于私人聊天问题,如果您在将其与我发送的服务器端代码进行比较之后查看我从“update_users”事件发送的代码,您会发现可与之聊天的用户名列表不是一个,而是一个对象其中包含连接的用户名和 socket.id,这是我发送到服务器端的内容。请再次检查,感谢您的帮助
  • 非常感谢兄弟!你是一个保护者,在你指出你发现的错误之后,我决定再看看我的代码,我发现了另外 3 个就像你发现的那个一样,显然,不是全局的接收者变量在每一点都被重新声明,我的聊天应用现在可以运行了!非常感谢您的帮助
  • @matteospampani 嗨,希望你做得很好,如果你可以看看,我有一个非常相似的问题。 stackoverflow.com/questions/65277256/…
  • @kd12345 是的,这是类似的问题,但此评论是 4 年前提出的,现在套接字中的所有内容都已更改,我无法帮助您,抱歉... :-(
  • @matteospampani,感谢您回复我。实现套接字变得更加困难了吗?你建议我仍然使用套接字还是有更好的选择?
【解决方案2】:

由于您希望两方的消息在他们之间保持私密,我建议您为两方各自创建一个房间。就目前而言,它认为您正在向包含所有用户的房间中的所有各方发送/广播您的活动。

【讨论】:

    猜你喜欢
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    相关资源
    最近更新 更多