Write a chat application with HTML5 WebSockets and Node.js

The traditional web was not designed for bidirectional communication. It was mostly designed as request/response paradigm where a client can only make a request to server and server can only respond to that request. To make things easy and faster, HTML5 introduced amazing WebSocket.

HTML5 WebSockets

WebSocket is a low latency bi-directional persistent connection between server and client where both server and client can send messages to each other.

With help of WebSocket, we can easily write a chat application in Node.js by ws library. Make sure Node.JS is installed.

Node.js

First, create a directory for our chat application and cd to the directory. (e.g my-chat)
mkdir my-chat
cd my-chat

Then create a file named package.json inside the directory with the following content

{
"name": "websocket-chat",
"version": "0.0.1",
"description": "Chat application using websocket",
"dependencies": {}
}

For our project, we are going to use two dependencies. One is ws and another is express web framework. To populate dependencies run following command on your terminal.
npm install --save express
npm install --save ws

Now create a file named index.js and populate with following content

  1. var express = require('express'),
  2. app = express(),
  3. http = require('http').Server(app),
  4. WebSocketServer = require('ws').Server,
  5. wss = new WebSocketServer({
  6. port: 8080
  7. });
  8.  
  9. app.use(express.static('public'));
  10.  
  11. app.get('/', function(req, res) {
  12. res.sendFile(__dirname + '/index.html');
  13. });
  14.  
  15. wss.broadcast = function broadcast(data) {
  16. wss.clients.forEach(function each(client) {
  17. client.send(data);
  18. });
  19. };
  20.  
  21. wss.on('connection', function(ws) {
  22. ws.on('message', function(msg) {
  23. data = JSON.parse(msg);
  24. if (data.message) wss.broadcast('<strong>' + data.name + '</strong>: ' + data.message);
  25. });
  26. });
  27.  
  28. http.listen(3000, function() {
  29. console.log('listening on *:3000');
  30. });
  31.  

On above codes, first we declare some variable and initiate express and WebSocketServer on port 8080. Then declare public directory to serve css file. Then we wrote code for routing. After that, we declare wss.broadcast to send message to all connected clients. By wss.on we bind events for WebSocket connection and message event. At the end by http.listen our application can listen to port 3000.

As we can see, our routing will call index.html to serve html file, now we need to create index.html file. Write our html code to index.html with following content

  1. <!doctype html>
  2. <html>
  3.  
  4. <head>
  5. <title>WebSocket Chat</title>
  6. <link rel="stylesheet" type="text/css" href="style.css">
  7. <script src="http://code.jquery.com/jquery-3.0.0.slim.min.js"></script>
  8. </head>
  9.  
  10. <body>
  11. <form>
  12. <div id="name-div">
  13. <input id="name" name="name" autocomplete="off" autofocus placeholder="Enter your nickname" />
  14. <button>Submit</button>
  15. </div>
  16. <div id="welcome"></div>
  17. <ul id="messages"></ul>
  18. <div id="input-div">
  19. <input id="message" name="message" autocomplete="off" placeholder="Type your message here" />
  20. <button>Send</button>
  21. </div>
  22. </form>
  23.  
  24. <script>
  25. websocket = new WebSocket("ws://localhost:8080/");
  26. $('form').submit(function() {
  27. name = $('#name').val() ? $('#name').val() : 'Anonymous';
  28. $('#name-div').hide();
  29. $('#welcome').text('Hello ' + name);
  30. websocket.send(JSON.stringify({
  31. name: name,
  32. message: $('#message').val()
  33. }));
  34. $('#message').focus();
  35. $('#message').val('');
  36. return false;
  37. });
  38.  
  39. websocket.onmessage = function(evt) {
  40. $('#messages').append($('<li>').html(evt.data));
  41. };
  42.  
  43. websocket.onerror = function(evt) {
  44. $('#messages').append($('<li>').text('<span style="color: red;">ERROR:</span> ' + evt.data));
  45. };
  46. </script>
  47. </body>
  48.  
  49. </html>
  50.  

In HTML part, we use some form elements to post nickname and message to the server. Inside script tag, we use HTML5 WebSocket connection and their methods.

Lets add some css to make our chat looks beautiful. Create a public directory and a file named style.css inside public directory.

  1. * {
  2. margin: 0;
  3. padding: 0;
  4. box-sizing: border-box;
  5. }
  6. body {
  7. font: 13px Helvetica, Arial;
  8. }
  9. form input {
  10. border: 0;
  11. padding: 10px;
  12. width: 90%;
  13. margin-right: .5%;
  14. }
  15. form button {
  16. width: 9%;
  17. background: rgb(130, 224, 255);
  18. border: none;
  19. padding: 10px;
  20. }
  21. #name-div, #welcome {
  22. background: #AAA;
  23. padding: 10px;
  24. width: 100%;
  25. }
  26. #input-div {
  27. background: #000;
  28. padding: 3px;
  29. position: fixed;
  30. bottom: 0;
  31. width: 100%;
  32. }
  33. #messages {
  34. list-style-type: none;
  35. margin: 0;
  36. padding: 0;
  37. }
  38. #messages li {
  39. padding: 5px 10px;
  40. }
  41. #messages li:nth-child(odd) {
  42. background: #eee;
  43. }
  44.  

Let’s run our application. Write following command to terminal/console

node index.js

Then go to your browser and visit http://localhost:3000

For full application check my GitHub repository.

N.B: Style was copyed from  chat application in socket.io