node.jssocketschat

Nodejs Socket chat app : Need to display the online and offline status


I just created the chat app using Socket and nodejs.

i displayed all user who connected the socket. in my right side of the chat box

now i need the status of the user weather offline or online

here the code i used

index.html

<html>
  <head>
    <title>Socket.IO chat</title>
        <script src="/socket.io/socket.io.js"></script>
        <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
        <style>
    #chat{
            height:500px;
        }
        #contentWrap{
            display: none;
        }
        #chatWrap{
            float: left;
            border: 1px #000 solid;
        }
        </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>
            var socket = io.connect();

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

//list the user who connected
        socket.on('usernames', function(data){
            var html = '';
            for(i=0; i < data.length; i++){
                html += data[i] + '<br/>'
            }
              $('#users').html(html);
        });

//send the message
        $('#send-message').submit(function(e){
          e.preventDefault();
          socket.emit('send message', $('#message').val());
          $('#message').val('');
        });

        socket.on('new message', function(data){
          $('#chat').append('<b>' + data.nick + ': </b>' + data.msg + "<br/>");
        });

    </script>
    </body>
</html>

app.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
nicknames = [];

app.get('/', function(req, res){
    res.sendFile('index.html', { root: 'views'});
});


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

//new user 
    socket.on('new user', function(data, callback){

        if (nicknames.indexOf(data) != -1){
            callback(false);
        } else{
            callback(true);
            socket.nickname = data;
            nicknames.push(socket.nickname);
                console.log('user connected: ' + socket.nickname);
        //  io.emit('update_personal', nicknames + ': Online');

            updateNicknames();
        }
    });

// update all user name

    function updateNicknames(){
        io.sockets.emit('usernames', nicknames);

    }

// send message 

    socket.on('send message', function(data){
    console.log('message: ' + {msg: data, nick: socket.nickname});
        io.sockets.emit('new message', {msg: data, nick: socket.nickname});
    });

//disconnected service

    socket.on('disconnect', function(data){
        console.log('user disconnected:' + socket.nickname )
        if(!socket.nickname) return;
        nicknames.splice(nicknames.indexOf(socket.nickname), 1);
        updateNicknames();
    });

});

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

enter image description here


Solution

  • In your app.js :

    Change your nicknames array by this :

    nicknames = {}
    

    Then of the event 'new user' we need to change a little bit your code like this :

    if (nicknames.hasOwnProperty(data)){ //We check if data received is in nicknames array
        callback(false);
    } else{
        callback(true);
        socket.nickname = data;
        nicknames[socket.nickname] = {online: true}; //Then we put an object with a variable online
            console.log('user connected: ' + socket.nickname);
    //  io.emit('update_personal', nicknames + ': Online');
    
        updateNicknames();
    }
    

    After that you need to modify the disconnect event :

    socket.on('disconnect', function(data){
        console.log('user disconnected:' + socket.nickname )
        if(!socket.nickname) return;
        nicknames[socket.nickname].online = false; //We dont splie nickname from array but change online state to false
        updateNicknames();
    });
    

    In your index.html :

    socket.on('usernames', function(data){
        var html = '';
        for (var nickname in data) //Foreach all nicknames received in data
        {
            var isNicknameOnline = data[nickname].online //Get the online state
    
            //We test the online status
            if (isNicknameOnline)
            {
                var status = '<font color=green><b>Yes</b></font>'
            }
            else
            {
                var status = '<font color=red><b>No</b></font>'
            }
    
            html += nickname + ' (Online: ' + status + ')<br/>' //print the status
        }
        $('#users').html(html);
    });
    

    Then run your app.js and refresh your index.html.

    Be carefull, your offline list isn't saved into database or text file, so if you restart your app.js, list will be empty.