将私人消息发送到特定套接字ID

时间:2014-07-05 17:35:02

标签: javascript node.js sockets

我对如何改进此代码有疑问。我是Socket.IO的新手,我一直在YouTube上观看有关私人消息的视频教程。我只是想知道是否有更好的方法来改进以下代码行?

    var io = require('socket.io');

   exports.initialize = function(server){
    io = io.listen(server);
    var usernames = {};

    io.sockets.on('connection', function(socket){
        socket.on('new user', function(data, callback){
            if(data in usernames){
                callback(false);
            }else{
                callback(true);
                //save the username to the socket for retrieval
                socket.username = data;
                usernames[socket.username] = socket;
                io.sockets.emit('usernames', Object.keys(usernames));
            }
        });

        socket.on('sendMessage', function(data, callback){
            var msg = data.trim();
            if(msg.substr(0,3) === "/w "){
                msg = msg.substr(3);
                var space = msg.indexOf(" ");
                if( space !== 1){
                    var name = msg.substr(0, space);
                    msg = msg.substr(space+1);
                    if(name in usernames){                         
                        usernames[name].emit('new message', {message: msg, username: socket.username});
                    }   
                } else{ 
                    callback("error invalid user");
                }
            } else{
                //retrieve the username saved in the socket
                io.sockets.emit('new message', {message: data, username: socket.username});
            }

        });

        socket.on('disconnect', function(data){
            if(!socket.username) return;
            //NEW
            delete usernames[socket.nickname];
            // OLD
            //usernames.splice(usernames.indexOf(socket.username), 1);
            io.sockets.emit('usernames', usernames);
        });
    });
};

我试图使用:

io.sockets.socket(id)emit('new message', {message: msg, username: socket.username});

但它似乎不起作用。

1 个答案:

答案 0 :(得分:2)

我有一个示例教程(我的练习代码)。它将帮助您理解socket.io。 socket.io的新版本是1.0。它有点不同,我对此并不熟悉,我使用的是旧版本,但我知道新版本没有太大区别。请仔细阅读它仍然有价值的评论,其中包括

中的示例
  1. 简单信息
  2. 私信
  3. 公开信息
  4. 加入/离开小组
  5. 将Mesage分组到
  6. 在线/离线状态,在线用户数
  7. 代码: 的 Server.js

    /**
     * require socket.io and coonect to port , here port no is 1180
     */
    var io = require('socket.io').listen(1180);
    /**
     * An object to store Socket object of every user by name
     * @type {Object}
     */
    var onLine = {}
    /**
     * An object to store all groups name
     * @type {Object}
     */
    var group = {};
    
    var onLine = {}
    var onLineBySocket = {};
    /**
     * On Connection - When a client gets connected
     * @param  {Object} socket An Object to identifiy the remote user
     * or client. Every client has its own unique socket. This socket
     * variable corresponds to the client who has just initiated any
     * socket event. 
     * Many user can initiate same socket event simultaneously but
     * Under this block, Socket will remain unique for every one.
     * Socket object will belong to the client whose has just 
     * communicated with server
     */
    io.sockets.on('connection', function(socket) {
        /**
         * A simple socket event at server side.
         * Set up an identity over the network. Set client's name
         * using socket.set function.
         * @param  {String} name Set your name on network
         */
        socket.on('connectMe', function(data) {
            socket.set('name', data.name)
            onLine[data.name] = socket
            onLineBySocket[socket.id] = data.name
            socket.get('name', function (err, name) {
                if(!err) {
                    // send back acknowledgement to the client requested for
                    // connectMe or registeration over this socket network
                    socket.emit('connectionEstablished', name)
                    // notify all remote user about this new socket or client
                    socket.broadcast.emit('onLine',name)
                }
            });
        });
    
        /**
         * Predefined/Reserved event
         * whenever a client gets disconnecte from server, this event 
         * gets triggered
         * @return {[type]}      [description]
         */
        socket.on('disconnect', function() {
            console.log(onLineBySocket, 'onLineBySocket')
            socket.get('name', function (err, name) {
                if(!err) {
                    socket.broadcast.emit('notification', name + ' is now offLine')
                }
            });
        })
    
        /**
         * Socket Handler for sending private message to someone,
         * @param  {String} to  Send To
         * @param  {String} msg Message
         */
        socket.on('privateMessage', function(data) {
            socket.get('name', function (err, name) {
                if(!err) {
                    // get the user from list by its name to get its socket, 
                    // then emit event privateMessage
                    // again here we want to make you clear
                    // that every single client connection has its own
                    // unique SOcket Object, we need to get this Socket object
                    // to communicate with every other client. The socket variable
                    // in this scope is the client who wants to send the private 
                    // message but the socket of the receiver is not know.
                    // Get it from the saved list when connectMe handlers gets called
                    // by each user.
                    onLine[data.to].emit('newPrivateMessage',{from:name, msg:data.msg, type:'Private Msg'})
                }
            });
        });
    
    
        /**
         * Send Public Message or broadcast(to all except the sender itself)
         */
        socket.on('publicMessage', function(data) {
            socket.broadcast.emit('newPublicMessage',{from:data.from, msg:data.msg, type:'Public Msg'})
        });
    
        /**
         * Make and store some private rooms/group. For creating room
         * socket.io itself has no role, we are just saving it in an object
         * and we will refer this object when client wants to join
         * any group
         */
        socket.on('newGroup', function(data) {
            group[data.group] = data.group
            socket.emit('groupCreated',{from:'server', msg:'group ' + data.group + ' created'})
        });
    
        /**
         * send object to client which stores all group name
         */
        socket.on('getGroupList', function(data) {
            socket.emit('groupList',group)
        });
    
        /**
         * Join a room/group
         */
        socket.on('joinGroup', function(data) {
            if(group[data.group]) {
                socket.join(data.group)
                socket.emit('notification','You have joined ' + data.group)
            } else {
                socket.emit('notification','group ' + data.group + " doesn't exist")
            }
        });
    
        /**
         * Leave a room/group
         */
        socket.on('leaveGroup', function(data) {
            if(group[data.group]) {
                socket.leave(data.group)
                socket.emit('notification','You have Left ' + data.group)
            } else {
                socket.emit('notification','group ' + data.group + " doesn't exist")
            }
        });
    
        /**
         * Broadcast message to every member of particular group
         * using broadcast.to
         */
        socket.on('groupMessage', function(data) {
            if(group[data.group]) {
                socket.broadcast.to(group[data.group]).emit('groupMessage',{from:data.from, msg:data.msg})
                socket.emit('notification','Message send')
            } else {
                socket.emit('notification','group ' + data.group + " doesn't exist")
            }
        });
    });
    

    代码: Client.js

    /**
     * Connect to remote host
     * @param  {String} IP Address of remote host with Port No.
     * @return {Object}
     */
    var socket = io.connect('http://localhost:1180');
    
    /**
     * get User Name from url
     * @type {String} - url
     */
    //var myName = window.location.search.match(/=(\w+)/)[1];
    var myName = "user"
    
    // Some predefined/reserved socket events
    /**
     * Checking Status of My Connection
     * If Connection gets disconnect, socket will try to auto-connect after some interval
     */
    socket.on('reconnecting', function(data) {
        console.log('Trying to Re-Connect')
    });
    
    /**
     * If socket founds Connection then it started process of connection
     * this is connnecting
     */
    socket.on('connecting', function() {
        console.log('Connecting')
    })
    /**
     * Event triggered when socket gets connected successfully
     */
    socket.on('connect', function() {
        console.log('Connected')
    });
    
    /**
     * Though we have connected to the socket without any kind
     * of authorisation and any identity. Let's set up an identity
     * over the network. Set your name.
     * @param  {String} name Set your name on network
     */
    function connectMe(name) {
        socket.emit('connectMe', {
            name: name
        });
        myName = name
    }
    
    /**
     * call connectMe function. It will emit a socket request to server
     * to set your name.
     * For this we will use socket.set and socket.get at server side
     */
    connectMe(myName)
    
    /**
     * User Defined Socket Handler/Event
     * @param  {String} name send by server
     * @return {[type]}
     */
    socket.on('connectionEstablished', function(name) {
        console.log('Welcome: ' + name)
    })
    
    /**
     * Want to know who has just come onLine
     */
    socket.on('onLine', function(name) {
        console.log(name + ' is now onLine')
    })
    
    /**
     * Send private message to someone,
     * server will append your name in 'From' 
     * at server side using socket.get
     * @param  {String} to  Send To
     * @param  {String} msg Message
     */
    function privateMessage(to, msg) {
        socket.emit('privateMessage', {
            to: to,
            msg: msg
        });
    }
    /**
     * Receive New Private Message
     * data.type added by server
     */
    socket.on('newPrivateMessage', function(data) {
        console.log(data.type + ' from ' + data.from + ': ' + data.msg)
    })
    
    /**
     * Send Public Message or broadcast(to all except me)
     * server will append your name in 'From' 
     * at server side using socket.get
     * @param  {String} msg Message
     */
    function publicMessage(msg) {
        socket.emit('publicMessage', {
            from: myName,
            msg: msg
        });
    }
    /**
     * Receive New Public Message
     * data.type added by server
     */
    socket.on('newPublicMessage', function(data) {
        console.log(data.type + ' from ' + data.from + ': ' + data.msg)
    })
    
    /**
     * Make some private rooms/group
     * @param  {String} group Name of the Group
     */
    function createGroup(group, msg) {
        socket.emit('newGroup', {
            group: group
        });
    }
    
    /**
     * Acknowledgemenet from server, group created
     * data.from, data.msg added by server
     */
    socket.on('groupCreated', function(data) {
        console.log(' from ' + data.from + ': ' + data.msg)
    })
    
    /**
     * Get List of available groups from server
     */
    function getGroupList() {
        socket.emit('getGroupList');
    }
    
    /**
     * List of all groups from server
     */
    socket.on('groupList', function(data) {
        console.log(' groupList ', data)
    })
    
    /**
     * Join a room/group
     * @param  {String} group Name of the group to join
     */
    function joinGroup(group) {
        socket.emit('joinGroup', {
            group: group
        });
    }
    
    /**
     * Send group Messages (To All in Group except me)- Not Public Message(To All)
     * @param  {String} group GroupName in which you want to send message
     * @param  {String} msg   Message
     */
    function groupMessage(group, msg) {
        socket.emit('groupMessage', {
            group: group,
            from: myName,
            msg: msg
        });
    }
    
    /**
     * Receive group message
     */
    socket.on('groupMessage', function(data) {
        console.log('Group Mesage from ' + data.from + ': ' + data.msg)
    })
    
    /**
     * Leave a room/group
     * Stop receiving messages from a group
     * @param  {String} group Name of the group to Leave
     */
    function leaveGroup(group) {
        socket.emit('leaveGroup', {
            group: group
        });
    }
    
    /**
     * Get Custom Notifications or Error messages from Server
     */
    socket.on('notification', function(msg) {
        console.log(msg)
    })