1

I have a question on how to improve this code. I'm a newbie with Socket.IO and I've been watching a video tutorial on YouTube about private messaging. I'm just wondering if there is a better way to improve the following lines of code?

    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);
        });
    });
};

I was trying to use:

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

But it doesn't seem to work.

James M
  • 18,506
  • 3
  • 48
  • 56
Aoi
  • 1,015
  • 6
  • 14
  • 27

1 Answers1

3

I have a sample tutorial(my practice code). It will help you to understand socket.io. New version of socket.io is 1.0. It is little bit different and I am not so much familiar with this, I am using older version but I know there is not much difference in new Ver. Please go through the comments it is still valuable, It includes example from

  1. Simple Message
  2. Private Message
  3. Public Message
  4. Join/Leave a group
  5. Group Mesage to
  6. Status online/offline and no of online users

Code: 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")
        }
    });
});

Code: 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)
})
Harpreet Singh
  • 2,651
  • 21
  • 31
  • just found an answer here http://stackoverflow.com/questions/24041220/sending-message-to-a-specific-id-in-socket-io-1-0 – Aoi Jul 06 '14 at 11:40