Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple TCP based chat server written in node.js
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
// Start a TCP Server
net.createServer(function (socket) {
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the chat\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the chat.\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
}).listen(5000);
// Put a friendly message on the terminal of the server.
console.log("Chat server running at port 5000\n");
@nimish-khanolkar

This comment has been minimized.

Show comment
Hide comment
@nimish-khanolkar

nimish-khanolkar May 10, 2013

hey, i wrote almost the same code myself, am new to node.js. But what is happening is when i use it via telnet, the server transmits each keystroke at a time than whole sentences. doesnt this happen with your code?

hey, i wrote almost the same code myself, am new to node.js. But what is happening is when i use it via telnet, the server transmits each keystroke at a time than whole sentences. doesnt this happen with your code?

@joseprl89

This comment has been minimized.

Show comment
Hide comment
@joseprl89

joseprl89 Jun 11, 2013

is there a missing semicolon at:

// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort

?

is there a missing semicolon at:

// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort

?

@mouseroot

This comment has been minimized.

Show comment
Hide comment

yea

@JJJollyjim

This comment has been minimized.

Show comment
Hide comment
@JJJollyjim

JJJollyjim Jun 20, 2013

@joseprl89 JavaScript doesn't need semicolons, it works fine.

@joseprl89 JavaScript doesn't need semicolons, it works fine.

@iamtrk

This comment has been minimized.

Show comment
Hide comment
@iamtrk

iamtrk Jul 10, 2013

hey nimish ,What actually happening in your case is you are transmitting the data to your self also besides other sockets. You need to remove yourself from the list while writing the data.
if (client === sender) return;does the work in the case of above chat server code.

iamtrk commented Jul 10, 2013

hey nimish ,What actually happening in your case is you are transmitting the data to your self also besides other sockets. You need to remove yourself from the list while writing the data.
if (client === sender) return;does the work in the case of above chat server code.

@murataka

This comment has been minimized.

Show comment
Hide comment

murataka commented Nov 1, 2013

buggy

@manuel-di-iorio

This comment has been minimized.

Show comment
Hide comment
@manuel-di-iorio

manuel-di-iorio Feb 10, 2014

socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});

if you broadcast every time the datas when received, you'll have a loop of broadcast :\

mark broadcast "abc" to rick
rick broadcast "abc" to mark
{loop}

socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});

if you broadcast every time the datas when received, you'll have a loop of broadcast :\

mark broadcast "abc" to rick
rick broadcast "abc" to mark
{loop}

@Capaverde

This comment has been minimized.

Show comment
Hide comment
@Capaverde

Capaverde Feb 13, 2014

I'd like to know if it is possible to make the client in node, instead of using telnet.

I'd like to know if it is possible to make the client in node, instead of using telnet.

@gooooloo

This comment has been minimized.

Show comment
Hide comment
@gooooloo

gooooloo Feb 26, 2014

Thanks. I am new to node.js socket. Your code does help me to understand how to use.

Thanks. I am new to node.js socket. Your code does help me to understand how to use.

@rafael-garcia

This comment has been minimized.

Show comment
Hide comment
@rafael-garcia

rafael-garcia Mar 22, 2014

@xeryan have you tested the code?

Because I did and could not reproduce what you've said.

Try running the server and then connecting via telnet, at least with two clients simultaneously.

Btw, the server will not (endlessly) loop the messages because it uses each socket to broadcast the messages. And as we know, each socket is linked to one client only.

@xeryan have you tested the code?

Because I did and could not reproduce what you've said.

Try running the server and then connecting via telnet, at least with two clients simultaneously.

Btw, the server will not (endlessly) loop the messages because it uses each socket to broadcast the messages. And as we know, each socket is linked to one client only.

@graphicbeacon

This comment has been minimized.

Show comment
Hide comment
@graphicbeacon

graphicbeacon Apr 11, 2014

Thanks for this creationix. Didn't realise how simple it was to create a TCP chat server. I put together an implementation based on yours with some tweaks in my gist–would be great to get your thoughts on it–https://gist.github.com/graphicbeacon/10422384

Thanks for this creationix. Didn't realise how simple it was to create a TCP chat server. I put together an implementation based on yours with some tweaks in my gist–would be great to get your thoughts on it–https://gist.github.com/graphicbeacon/10422384

@anshulgithub

This comment has been minimized.

Show comment
Hide comment
@anshulgithub

anshulgithub May 19, 2014

How we can use this code for send message to single user only?

How we can use this code for send message to single user only?

@moosaviamir

This comment has been minimized.

Show comment
Hide comment
@moosaviamir

moosaviamir Dec 30, 2014

Nice code! Thanks.
what if i want to close connection of a client in server by force? I want to authenticate my users and if it failed close connection!

Nice code! Thanks.
what if i want to close connection of a client in server by force? I want to authenticate my users and if it failed close connection!

@samarthagarwal

This comment has been minimized.

Show comment
Hide comment
@samarthagarwal

samarthagarwal May 13, 2015

I am seeing some special character in the first chat message! Seems like data is not set for the first time or it required some decoding because it shows lot of special characters. After one message is sent, it becomes okay.
PS: I am using putty as the telnet client.

I am seeing some special character in the first chat message! Seems like data is not set for the first time or it required some decoding because it shows lot of special characters. After one message is sent, it becomes okay.
PS: I am using putty as the telnet client.

@vaghul

This comment has been minimized.

Show comment
Hide comment
@vaghul

vaghul Mar 22, 2016

Hi ,
Is there a way to send custom values on the handshake process ? i.e send custom data only when connecting the first time.

vaghul commented Mar 22, 2016

Hi ,
Is there a way to send custom values on the handshake process ? i.e send custom data only when connecting the first time.

@mmpataki

This comment has been minimized.

Show comment
Hide comment
@mmpataki

mmpataki Nov 16, 2016

@nimish: If you are using a windows telnet client this will surely happen. Use some other telnet client which buffers the keystrokes until you press ENTER like telnet in Linux

@nimish: If you are using a windows telnet client this will surely happen. Use some other telnet client which buffers the keystrokes until you press ENTER like telnet in Linux

@msgallagher

This comment has been minimized.

Show comment
Hide comment
@msgallagher

msgallagher Mar 5, 2017

i have a version working with line-by-line chats for windows telnet if anyone in interested...

i have a version working with line-by-line chats for windows telnet if anyone in interested...

@raghav1803

This comment has been minimized.

Show comment
Hide comment
@raghav1803

raghav1803 Jul 3, 2017

@msgallagher I am interested in this version.

@msgallagher I am interested in this version.

@jampola

This comment has been minimized.

Show comment
Hide comment
@jampola

jampola Jul 19, 2017

Not wanting to steal your thunder, but I actually had a student friend of mine request a really dumb'ed down version of something like this.

If you need a simple boiler plate for doing this, this should help out.

let net = require('net');

net.createServer(function(s){
  s.on('data', function(data){
    broadcast("> " + data);
  })
  function broadcast(message){
    process.stdout.write(message);
  }
}).listen(1234);

jampola commented Jul 19, 2017

Not wanting to steal your thunder, but I actually had a student friend of mine request a really dumb'ed down version of something like this.

If you need a simple boiler plate for doing this, this should help out.

let net = require('net');

net.createServer(function(s){
  s.on('data', function(data){
    broadcast("> " + data);
  })
  function broadcast(message){
    process.stdout.write(message);
  }
}).listen(1234);
@abhilash007

This comment has been minimized.

Show comment
Hide comment
@abhilash007

abhilash007 Jul 27, 2017

is it possible to integrate EXPRESS with NET(let net = require('net'))?

is it possible to integrate EXPRESS with NET(let net = require('net'))?

@myeac

This comment has been minimized.

Show comment
Hide comment
@myeac

myeac Mar 2, 2018

how can i test this code?? im really new with Node.js and i'm trying to learn this Technology in order to créate a nodejs server that helps with the communication between 3 android devices. I will apreciate any help or recomendaciones. Thanks! :D

myeac commented Mar 2, 2018

how can i test this code?? im really new with Node.js and i'm trying to learn this Technology in order to créate a nodejs server that helps with the communication between 3 android devices. I will apreciate any help or recomendaciones. Thanks! :D

@hscheuerle

This comment has been minimized.

Show comment
Hide comment
@hscheuerle

hscheuerle Apr 11, 2018

This is great for learning the server-side. I couldn't figure out how to write in Node without an npm package like ws or websocket. I've always learned the most implementing production APIs with lower level libraries.

@vaghul, also looking to learn protocol messages by writing the headers myself. They are so thoroughly reused that there seems to be no reason for simple instructions to exist. Let me know what you found since your post if you see this.

@myeac, you probably figured it out by now, but check out any starter nodejs tutorials, its 'node ' to run node scripts.

This is great for learning the server-side. I couldn't figure out how to write in Node without an npm package like ws or websocket. I've always learned the most implementing production APIs with lower level libraries.

@vaghul, also looking to learn protocol messages by writing the headers myself. They are so thoroughly reused that there seems to be no reason for simple instructions to exist. Let me know what you found since your post if you see this.

@myeac, you probably figured it out by now, but check out any starter nodejs tutorials, its 'node ' to run node scripts.

@MarkSh1

This comment has been minimized.

Show comment
Hide comment
@MarkSh1

MarkSh1 May 17, 2018

I think it will be better for low speed users :

socket.on('myEvent', function (message)
{
  socket.write(message);
}
);
...........
// Send a message to all clients
function broadcast(message, sender) 
{
  clients.forEach(function (client) {
          // Don't want to send it to sender
          if (client === sender) return;
          client.emit('myEvent', message);
  });
 // Log it to the server output too  
  process.stdout.write(message)
}


MarkSh1 commented May 17, 2018

I think it will be better for low speed users :

socket.on('myEvent', function (message)
{
  socket.write(message);
}
);
...........
// Send a message to all clients
function broadcast(message, sender) 
{
  clients.forEach(function (client) {
          // Don't want to send it to sender
          if (client === sender) return;
          client.emit('myEvent', message);
  });
 // Log it to the server output too  
  process.stdout.write(message)
}


@codedokode

This comment has been minimized.

Show comment
Hide comment
@codedokode

codedokode May 30, 2018

Found this using Google. Sorry, but this code has two important mistakes. The main mistake is that when client sends a message to the chat, it won't come as a single packet. It can be broken into parts (and multibyte characters can be broken into bytes) and on('data', ...) callback would be called several times. That is because TCP is a stream-oriented protocol and doesn't have a concept of "messages". To fix this, you need some reader that will read data from the socket, collect it (it is called "to buffer the data"), split at new lines and emit line-by-line. Luckily, there is a library for that: carrier:

    var lineReader = carrier.carry(socket);
    lineReader.on('line',  function(line) {
        console.log('got one line: ' + line);
    });

Second, you don't handle errors. There always can be errors while working with network, something can fail. Node.JS by default doesn't report these errors so it is your responsibility. Without displaying them it would be really difficult to debug your program. You won't even know that something was wrong. So you should add a code like this:

socket.on('error', function (e) {
    console.log("Error on client socket " + socket.name);
    console.log(e);
});

The same should be done for server socket that accepts connections:

var serverSocket = net.createServer(...);
serverSocket.on('error', function (e) {
    console.log("Error on server socket");
    console.log(e);
});

References:

Update: as I have read in Node docs, you don't have to handle errors. If you don't set an error handler, any error will just crash your script so you will know about it. But if you want your server to continue working if there is problem with a single client then you should write an error handler that prints the error and closes broken client's connection.

codedokode commented May 30, 2018

Found this using Google. Sorry, but this code has two important mistakes. The main mistake is that when client sends a message to the chat, it won't come as a single packet. It can be broken into parts (and multibyte characters can be broken into bytes) and on('data', ...) callback would be called several times. That is because TCP is a stream-oriented protocol and doesn't have a concept of "messages". To fix this, you need some reader that will read data from the socket, collect it (it is called "to buffer the data"), split at new lines and emit line-by-line. Luckily, there is a library for that: carrier:

    var lineReader = carrier.carry(socket);
    lineReader.on('line',  function(line) {
        console.log('got one line: ' + line);
    });

Second, you don't handle errors. There always can be errors while working with network, something can fail. Node.JS by default doesn't report these errors so it is your responsibility. Without displaying them it would be really difficult to debug your program. You won't even know that something was wrong. So you should add a code like this:

socket.on('error', function (e) {
    console.log("Error on client socket " + socket.name);
    console.log(e);
});

The same should be done for server socket that accepts connections:

var serverSocket = net.createServer(...);
serverSocket.on('error', function (e) {
    console.log("Error on server socket");
    console.log(e);
});

References:

Update: as I have read in Node docs, you don't have to handle errors. If you don't set an error handler, any error will just crash your script so you will know about it. But if you want your server to continue working if there is problem with a single client then you should write an error handler that prints the error and closes broken client's connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment