javascript - 聊天中带有 "/w"的 Nodejs 私信

标签 javascript node.js socket.io

我是一个nodejs菜鸟,但尝试与一些用户创建一个聊天室,它有效,但现在我想在聊天中使用命令“/w”发送私有(private)消息,例如:

/w 大卫你好,你好吗?

只有 David 可以读取该消息。 问题是每个人都可以阅读我的私有(private)消息,并且例如大卫,从所有用户那里接收它,wtf?

这是我的 server.js

//Création d'un serveur
var http = require('http');
var md5 = require('MD5');
var io = require('socket.io');

function rand(){
    return (Math.round(Math.random())-0.5); 
}

var colors = new Array('#a8291a','#a5992f','#f24816','#24dc61','#a7954a','#b2676e','#ec4458');

//Démarrage du serveur.
httpServer = http.createServer(function(req,res){
    console.log('Page affichée par un utilisateur');
})

httpServer.listen('4120');

var users = {};
var clients = [];
/**
* Installation socket.io : npm install socket.io
*/

io = io.listen(httpServer);


io.sockets.on('connection', function(socket){

    var me = false;

    for(var k in users){
        socket.emit('newuser', users[k]);
    }


    /**
    * Reception de message.
    **/

    socket.on('newmsg',function(message){
        message.user = me;
        date = new Date();
        message.h = date.getHours();
        message.m = date.getMinutes();
        message.s = date.getSeconds();
        io.sockets.emit('newmsg', message);
    });

    /**
    * Connexion.
    **/

    socket.on('login', function(user){
        var hs = socket.handshake;
        me = user;
        me.id = user.mail.replace('@','-').replace('.','-');
        me.avatar = 'https://gravatar.com/avatar/' + md5(user.mail) + '?s=32&d=identicon';
        me.color = colors[Math.floor(Math.random()*colors.length)];
        clients[me.id] = socket.id;
        socket.emit('logged');
        users[me.id] = me;
        //io.sockets.emit permet d'envoyer l'action à tous les utilisateurs.
        io.sockets.emit('newuser',me);
    });

    /**
    *   Inscription à une room.
    **/

    socket.on("private", function(data) {
        io.to(clients[data.dest]).emit("private", { from: me.id, to: data.dest, msg: data.msg });
        io.to(clients[me.id]).emit("private", { from: me.id, to: data.dest, msg: data.msg });
   });

    /**
    * Deconnexion.
    **/
    socket.on('disconnect', function(){
        if(!me)
            return false;
        delete users[me.id];
        io.sockets.emit('discuser',me);
    })
});

这是我的 client.js

(function($){

    var socket = io.connect('http://192.168.1.72:4120');
    var msg = $('#msg').html();
    $('#msg').remove();

    $('#loginform').submit(function(event){
        event.preventDefault();
        socket.emit('login', {
            username : $('#username').val(),
            mail : $('#mail').val()
        })
    });

    socket.on('logged', function(){
        $('#login').fadeOut();
        $('#form').fadeIn();
        $('#messages').fadeIn();
        $('#message').focus();
    });


    /**
    * Envois de message.
    **/

    $('#form').submit(function(event){
        event.preventDefault();

        //Le serveur se souvient de l'utilisateur connecté sur ce socket, pas besoin de le define.

        //Si le message n'est pas vide on envoie le message.
        if( $.trim( $('#message').val() ) != '' ){
            socket.emit('newmsg', {message: $('#message').val()});
            $('#message').val('');
            $('#message').focus();
        }
    });

    socket.on('newmsg', function(message){
        if (message.message.substr(0, 3) == "/w "){
            var destinataire_id = message.message.split(' ')[1];
            console.log(destinataire_id);
            message.message = message.message.replace('/w ','').replace(destinataire_id,'');
            socket.emit("private", { msg: message.message, dest: destinataire_id});

        }else{
            if (($('#messages')[0].scrollHeight - $('#messages').scrollTop()) == $('#messages').height())
            {
                $('#messages').append('<div class="message">'+Mustache.render(msg, message)+'</div>');
                $('#messages').scrollTop($('#messages')[0].scrollHeight);
            }else{
                $('#messages').append('<div class="message">'+Mustache.render(msg, message)+'</div>');
            }
        }

    });

    socket.on("private", function(data) {    
        $('#messages').append('<li class="private"><em><strong>'+ data.from +' -> '+ data.dest +'</strong>: '+ data.msg +'</em></li>');
    })


    /**
    * Gestion des connectés.
    **/
    socket.on('newuser', function(user){
        $('#users').append('<div id="'+ user.id +'" class="row one_user">'+
                                '<div class="col-md-2 vcenter"><img src="'+ user.avatar +'"/></div>'+
                                '<div class="col-md-9 vcenter">'+ user.username +'</div>'+
                                '</div>'
                            );
    })

    socket.on('discuser', function(user){
        $('#' + user.id).remove();
    })


    /* socket.emit('send message', {
        room: conversation_id,
        message: $('#message_'+conversation_id)
    }); */

})(jQuery);

如果你需要的话,我的html:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" href="css/bootstrap.min.css">
        <style>     

        #messages{
            min-height:300px;
            overflow-y:auto;
            max-height:600px;
        }

        #messages,#form{
            display:none;
        }

        .clear{
            clear:both;
        }

        .vcenter {
            display: inline-block;
            vertical-align: middle;
            float: none;
        }

        .vtop {
            display: inline-block;
            vertical-align: top;
            float: none;
        }

        .top-margin{
            margin-top:25px;
        }

        small{
            font-size:70%;
        }

        .message{
            margin:5px 0;
        }

        ::-webkit-scrollbar {
            width: 12px;
        }

        ::-webkit-scrollbar-track {
            -webkit-box-shadow: inset 0 0 6px rgba(214, 94, 0, 0.5); 
            border-radius: 5px;
        }

        ::-webkit-scrollbar-thumb {
            border-radius: 5px;
            -webkit-box-shadow: inset 0 0 6px rgba(214, 94, 0, 0.5); 
        }

        #users>div{
            margin-top:10px;
        }

        </style>
    </head>
    <body>
        <div class="container top-margin">
            <div class="col-md-9">
                <div class="row panel panel-default" id="messages">
                <ul class="nav nav-tabs">
                    <li class="active">
                        <a href="#"># All</a>
                    </li>
                </ul>
                    <div class="message" id="msg" style="display:none;">
                            <style>
                                .info_{{ user.username }} {
                                   min-height: 50px;
                                   position: relative;
                                   -moz-border-radius:    10px;
                                   -webkit-border-radius: 10px;
                                   border-radius:         5px;
                                   padding:8px;
                                   background : {{ user.color }}
                                }
                                .info_{{ user.username }}:before {
                                   content:"";
                                   position: absolute;
                                   right: 100%;
                                   top: 10px;
                                   width: 0;
                                   height: 0;
                                   border-top: 5px solid transparent;
                                   border-bottom: 5px solid transparent;
                                   border-right : 14px solid {{ user.color }}
                                }
                            </style>
                            <div style="text-align:center;" class="col-md-2 vtop">
                                <img src="{{{user.avatar}}}" />
                                <p><strong>{{user.username}}</strong></p>
                            </div>
                            <div class="info_{{ user.username }} col-md-9 vtop">
                                {{message}} <br/>
                                <small>Posté à : {{h}}:{{m}}:{{s}}</small>
                            </div>
                    </div>
                </div>
                <form class="row" action="" id="form">
                      <div class="col-md-12">
                        <div class="input-group">
                            <input id="message" type="text" class="form-control" placeholder="Type your text here...">
                            <span class="input-group-btn">
                                <button class="btn btn-default" type="submit">Envoyer</button>
                            </span>
                        </div>
                      </div>    
                </form>
            </div>
            <div class="col-md-3">
                <div class=" panel panel-default">
                    <div class="panel-heading">Utilisateurs en ligne</div>
                    <div class="panel-body" id="users"></div>
                </div>
            </div>  
        </div>
        <div id="login">
            <form action="" id="loginform">
                <h1>Bienvenue</h1>
                <p>Veuillez vous connecter pour continuer.</p>
                <input type="text" name="login" id="username" placeholder="Nom user">
                <input type="mail" name="mail" id="mail" placeholder="mail">
                <input type="submit" value="Envoyer">
            </form>
        </div>

        <script type="text/javascript" src="js/jquery.min.js"></script>
        <script src="http://192.168.1.72:4120/socket.io/socket.io.js"></script>
        <script src="js/mustache.min.js"></script>
        <script src="js/bootstrap.min.js"></script>
        <script type="text/javascript" src="js/client.js"></script>
    </body>
</html>

如果您知道我的私有(private)消息如何运作?

谢谢!!

最佳答案

最简单的想法;将他们的用户名和 socket.id 一起存储在一个对象或另一个数据存储中。

服务器端;

var users = {};

socket.on('login', function(user){
  // on connection store users, you can delete object properties on disconnect
  users[user.username] = socket.id; // usernames and their socket ids are related now.
});
socket.on('newmsg', function(message){
   if(message.indexOf('/w') == 0){ // Check, is user whispering
      var messageArray = message.split(' '); // Split string as array
      var username = messageArray[1]; // we got username
      var msg = messageArray.splice(2).join(' '); // join message's words
      socket.broadcast.to(users[username]).emit('newmsg', msg); // david gets message (users[username] gives his socket.id)
   }else{
      // send message everybody
   }
});

所以我们有了最简单的私有(private)消息传递机制。

关于javascript - 聊天中带有 "/w"的 Nodejs 私信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37206010/

相关文章:

javascript - 如何递归嵌套对象值以使父对象包含相应的命名集合?

javascript - 双击div,p,span时如何获取选中的单词?

javascript - 如何通过 "foreign key"关系组合json对象

javascript - 如何处理哪个子进程获得 socket.io 套接字句柄

java - 在 android 上使用 Socket.IO 总是返回 XHR 轮询错误

iOS模拟器测试多人游戏

javascript - React - 如果媒体类型是照片则显示照片

javascript - NodeJS res.write 不起作用控制台工作

node.js - (双代理)node js 使用 node-http-proxy 在企业代理后面创建代理服务器

javascript - 如何在 grunt.initConfig() 之前执行异步操作?