与node.js

时间:2016-02-11 08:21:06

标签: node.js socket.io socket.io-1.0

我正在尝试创建一个聊天系统,用户可以向所有人发送消息(此消息显示在id为“chat”的div中)并且我已经实现了此功能。现在我想实现私聊。用户可以点击右栏上的另一个用户名(显示所有登录用户),一旦他点击用户名,就会出现一个小窗口(div为“chatpopup”类),在这个窗口中有一个提交按钮和一个输入要填写的消息文本,一旦点击提交按钮,该消息应该发送给其他用户。

这就是我所拥有的,如果我点击一个用户(在屏幕的右侧),会显示一个小窗口(chatpopup)但是当我尝试在这个小窗口内提交表单时,应用程序崩溃了。 我还想收到关于建立私人聊天的一些提示,例如我如何在用户的客户端打开一个应该接收消息的新窗口(带有消息接收)?

的index.html

<html>
<head>
    <title>Chat with socket.io and node.js</title>
    <style>
        #contentWrap
        {
            width:100%;
            display: none;
        }
        #chatWrap {float: left; width:80%;}
        #chat
        {
            height:500px;
            width:96%;
            border: 1px #000 solid;
            padding-left:2%;
            padding-right:2%;
        }
        #users 
        {
            margin-left:82%; width:15%;
            height:500px; 
            border: 1px #000 solid; 
            text-align:right;
        }
        #send-message {margin-top:3%; width:100%;}
        #message {width:80%;}
        .err1r{ padding-top:1%;
            color: red;
        }
        .whisper{
            color: gray;
            font-style: italic;
        }
        p.sideusername:nth-child(even) {background-color:#FAFAFA; padding-bottom:5%; padding-top:5%;}
        p.sideusername:nth-child(odd) {background-color: #f5f5f0; padding-bottom:5%; padding-top:5%;}
        .chatpopup {width:350px; height: 250px; background-color:blue;}
        #interlocutore {background-color:red; height: 30px; text-align: left;}
        #msgspace {height:150px; background-color:yellow;}
    </style>
</head>
<body>
    <div id="nickWrap">
        <p>Enter a username:</p>
        <p id="nickError"></p>
        <form id="setNick">
            <input size="35" id="nickname"></input>
            <input type="submit"></input>
        </form>
    </div>

    <div id="contentWrap">
        <div id="chatWrap">
            <div id="chat"></div>
            <form id="send-message">
                <input size="35" id="message"></input>
                <input type="submit"></input>
            </form>

        </div>
        <div id="users"></div>
    </div>


    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        jQuery(function($){
            var socket = io.connect();
            var $nickForm = $('#setNick');
            var $nickError = $('#nickError');
            var $nickBox = $('#nickname');
            var $users = $('#users');
            var $messageForm = $('#send-message');
            var $messageFormPopup = $('#send-message-popup');
            var $messageBox = $('#message');
            var $messageBoxPopup = $('#messagePopup');
            var $chat = $('#chat');

            $nickForm.submit(function(e){
                e.preventDefault();
                socket.emit('new user', $nickBox.val(), function(data){
                    if(data){
                        $('#nickWrap').hide();
                        $('#contentWrap').show();
                    } else{
                        $nickError.html('That username is already taken!  Try again.');
                    }
                });
                $nickBox.val('');
            });

            socket.on('usernames', function(data){
                $users.empty();
                for(var i=0; i < data.length; i++){
                    $users.append('<p class="sideusername">' + data[i] + "</p>");   
                }
            });

            $messageForm.submit(function(e)
            {
                e.preventDefault();
                socket.emit('send message', $messageBox.val(), function(data)
                {
                });
                $chat.append('<span class="error">' + data + "</span><br/>");
                $messageBox.val('');
            });

            $messageFormPopup.submit(function(e)
            {
                e.preventDefault();
                socket.emit('send popup message', $messageBoxPopup.val(), function(dataPopup)
                {

                });
                $messageBoxPopup.val('');
            });

            socket.on('load old msgs', function(docs){
                for(var i=docs.length-1; i >= 0; i--){
                    displayMsg(docs[i]);
                }
            });

            socket.on('new message', function(data){
                displayMsg(data);
            });

            function displayMsg(data){
                $chat.append('<span class="msg"><b>' + data.nick + ': </b>' + data.msg + "</span><br/>");
            }

            socket.on('whisper', function(data){
                $chat.append('<span class="whisper"><b>' + data.nick + ': </b>' + data.msg + "</span><br/>");
            });

            $(document).on("click", ".closepopup", function() {
                $(this).parents('.chatpopup').hide();
            });

            $(document).on("click", ".sideusername", function()
            {
                var interlocutore = $(this).text();
                $chat.append('<div class="chatpopup"><table><tr><td id="interlocutore"></td><td><p class="closepopup">X</p></td></tr><tr><td colspan="2" id="msgspace"></td></tr><tr><td colspan="2"><form id="send-message-popup"> <input size="35" id="messagePopup"></input><input type="submit"></input></form></td></tr></table></div>');
                $('#interlocutore').append(interlocutore);
            });

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

app.js

    var express = require('express'),
    app = express(),

server = require('http').createServer(app),
io = require('socket.io').listen(server),
mongoose = require('mongoose'),
users = {};
server.listen(3000);

    mongoose.connect('mongodb://localhost/chat', function(err)
    {
        if(err)
           console.log(err);
        else console.log('Connected to mongodb!');
    });

    var chatSchema = mongoose.Schema(
    {
        nick: String,
        msg: String,
        created: {type: Date, default: Date.now}
    });

    var Chat = mongoose.model('Message', chatSchema);
    app.get('/', function(req, res)
    {
        res.sendfile(__dirname + '/index.html');
    });

    io.sockets.on('connection', function(socket)
    {
        var query = Chat.find({});
        query.sort('-created').limit(8).exec(function(err, docs)
        {  // carico gli ultimi 8 messaggi in ordine di data
            if(err) throw err;
            socket.emit('load old msgs', docs);
        });

        socket.on('new user', function(data, callback)
        {
            if (data in users)
                callback(false);
            else
            {
                callback(true);
                socket.nickname = data;
                users[socket.nickname] = socket;
                updateNicknames();
            }
        });


        function updateNicknames()
        {
            io.sockets.emit('usernames', Object.keys(users));
        }

        socket.on('send message', function(data, callback)
        {
                var msg = data.trim();
                var newMsg = new Chat({msg: msg, nick: socket.nickname});
                newMsg.save(function(err)
                {
                    if(err) throw err;
                    io.sockets.emit('new message', {msg: msg, nick: socket.nickname});
                });

                socket.on('disconnect', function(data)
                {
                    if(!socket.nickname) return;
                    delete users[socket.nickname];
                    updateNicknames();
                });
        });


        socket.on('send popup message', function(data, callback)
        {
            /*var msgPopup = dataPopup.trim();
            if (msgPopup !== "")
                users[interlocutore].emit('whisper', {msg: msgPopup, nick: socket.nickname});
            */
                var msg = data.trim()+" hello";
                var newMsg = new Chat({msg: msg, nick: socket.nickname});
                newMsg.save(function(err)
                {
                    if(err) throw err;
                    io.sockets.emit('new message', {msg: msg, nick: socket.nickname});
                });
            socket.on('disconnect', function(data)
            {
                if(!socket.nickname) return;
                delete users[socket.nickname];
                updateNicknames();
            });
        });
    });

2 个答案:

答案 0 :(得分:2)

要使用socket.IO创建私人聊天,您首先需要了解socket.IO中个房间的工作方式。你可以找到大量的教程。您还可以查看this帖子以获取帮助。

现在您需要扩展此功能以创建私人聊天系统。为此,您需要为每个已连接或联机的客户端提供唯一的 id socket.id 是每个客户在加入聊天时获得的唯一键。

在客户端,您可以向服务器发送名称以及消息。你这样做:

socket.emit('privateMessage', 'theUserName', message);

在服务器端,您可以管理已连接的用户数组,并保存其唯一的用户名或 ID

var connectedClients = {};

因此,每当用户连接到聊天时(您可能正在使用new user事件),请将用户的ID保存在connectedClients

connectedClients[username] = socket.id;

其中username是用户连接到聊天系统时发送到服务器的名称。 (我希望你知道怎么做。如果没有,请问我。)

然后我们让一个监听器听取privateMessage事件并向该特定用户发出消息,我们这样做:

socket.on('privateMessage', function(to, message) {
    var id = connectedClients[to];
    io.sockets.socket(id).emit('sendPrivateMessage', socket.username, message);
});

最后,在客户端,sendPrivateMessage的听众会收到该消息,您可以相应地更新您的视图。

答案 1 :(得分:0)

这个想法是服务器通过用户名保存与其连接的每个套接字:users[socket.nickname] = socket;

所以每当用户向另一个用户发送消息时 - 你应该发出一个事件 - 向其发送另一个用户的用户名 - 拿走该用户的套接字并向他发送消息:

客户端:

socket.emit('sendPrivate','someusername','message');
socket.on('privateMsg',function(from,msg){
 //write private message from user 'from'
});

服务器:

socket.on('sendPrivate',function(to,msg){
   users[to].emit('privateMsg',socket.username,msg);
});