0

I'm currently self-training in NodeJs and trying to perform a simple chat. To do so, I use the package 'json-socket' in order to exchange json objects between the clients and the server. The principle is simple :

  • I launch the server
  • Then each client has to give a pseudo
  • When done, it's registered on server side
  • Then when a client sends a message, it's broadcasted to all other clients

BUT I got a problem :

  • let's assume the server is launched
  • when the very first client connects, it happens nothing. I mean he's not registered on server side, and no logs on server side is displayed
  • I kill the session for this client (Ctrl + c) and try to make it connect again. This time it works, he's well registered
  • I launch a new client. This time he is registered 4 times :|
  • I launch another new client. This time he is registered 9 times :| :|

I just don't understand why. Please find the code below...

Server.js

var net = require('net'), JsonSocket = require('json-socket');

var sockets = [];

var server = net.createServer(function(socket)
{
    server.on('connection', function(socket) { //This is a standard net.Socket
        socket = new JsonSocket(socket); //Now we've decorated the net.Socket to be a JsonSocket

        console.log('Connection');

        socket.on('message', function(message) {

            console.log("0");

            if (message.isMessage == null)
            {
                console.log("1");
                var sender = message.pseudo;

                sockets.push({socket : socket, pseudo : sender});

                sockets.forEach(function(s)
                {
                    if (s.pseudo.toString() != sender.toString())
                        s.socket.sendMessage(sender + " vient de se connecter");
                });

                console.log(sender + " vient de se connecter");
                console.log("Il y a " + sockets.length + " clients connectés");
            }
            else
            {
                console.log("2");
                var sender = message.pseudo;
                sockets.forEach(function(s)
                {
                    if (s.pseudo.toString() != sender.toString())
                    {   
                        console.log("3");
                        s.socket.sendMessage(sender + " : " + message.message);
                    }
                });
            }
        });
    });

    socket.on('error', function()
    {
        socket.emit('end');
    });

    socket.on('end', function()
    {
        // TODO : fix this part
        //sockets.slice(sockets.indexOf(socket), 1);
        console.log("Il reste " + sockets.length + " clients connectés");
    });
});

server.on('listening', function()
{
    console.log('Server launched');
});

server.listen(3000);

Client.js

var net = require('net');
var stream = require('stream');
var JsonSocket = require('json-socket');
var readable = new stream.Readable();

var port = 3000; 
var host = '127.0.0.1';
var client = new JsonSocket(new net.Socket());

// first step : pseudo init
var pseudo = '';
console.log('Give a pseudo');
readable.setEncoding('utf8');

readable._read = function(size)
{
    process.stdin.removeAllListeners('data').on('data', function(chunk)
    {
        readable.push(chunk);
    });
};

readable.on('data', function(chunk)
{
    if (pseudo.length == 0)
    {
        // TODO : méthode utilitaire pour formatter la string moisie
        pseudo = chunk.toString().replace(/\r|\n/g, "");
        console.log("Bonjour " + pseudo);
        connect();
    }
    else
    {
    console.log("3");
        if (chunk.toString().replace(/\r|\n/g, "") == "exit")
        {
        console.log("4");
            client.sendEndMessage({pseudo : pseudo, message : chunk});
        }
        else
        {
        console.log("5");
            client.sendMessage({pseudo : pseudo, message : chunk, isMessage : true});
        }
    }   
});

function connect()
{
    client.connect(port, host);

    client.on('connect', function()
    {
        client.sendMessage({pseudo : pseudo});

        client.on('message', function(message) {
            console.log(message);
        });
    });

    client.on('error', function()
    {
        console.log("Perte de connexion");
        connect();
    });

    client.on('end', function()
    {
        process.stdin.pause();
    });
};

1 Answer 1

2

I think you will find it is because of this line in server.js being in the wrong place:

sockets.push({socket : socket, pseudo : sender});

It should be done as part of the "connection" handler and not every time there is a message.

Edit:

I ran your code and from the json-socket example, I did not pass in a callback function to createServer, rather I left creating the handlers separately: (this seems to work!)

var net = require('net'), JsonSocket = require('json-socket');
var sockets = [];
var server = net.createServer();

server.on('connection', function(socket) { //This is a standard net.Socket
    socket = new JsonSocket(socket); //Now we've decorated the net.Socket to be a JsonSocket

    console.log('Connection');

    socket.on('message', function(message) {

        console.log("0");

        if (message.isMessage == null)
        {
            console.log("1");
            var sender = message.pseudo;
        sockets.push({socket : socket, pseudo : sender});
        console.log('Clients connected =', sockets.length());

            sockets.forEach(function(s)
            {
                s.socket.sendMessage(sender + " vient de se connecter");
            });

            console.log(sender + " vient de se connecter");
            console.log("Il y a " + sockets.length + " clients connectés");
        }
        else
        {
            console.log("2");
            var sender = message.pseudo;
            sockets.forEach(function(s)
            {
                if (s.pseudo.toString() != sender.toString())
                {   
                    console.log("3");
                    s.socket.sendMessage(sender + " : " + message.message);
                }
            });
        }
    });
});

server.on('error', function()
{
    socket.emit('end');
});

server.on('end', function()
{
    // TODO : fix this part
    //sockets.slice(sockets.indexOf(socket), 1);
    console.log("Il reste " + sockets.length + " clients connectés");
});


server.on('listening', function()
{
    console.log('Server launched');
});

server.listen(3000);
Sign up to request clarification or add additional context in comments.

2 Comments

I'm sorry - it was late last night and I never got back to you so apologies!
I've edited the answer give some code that works for me... let me know how you get on!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.