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.
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.
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
var express = require('express'), app = express(), http = require('http').Server(app), WebSocketServer = require('ws').Server, wss = new WebSocketServer({ port: 8080 }); app.use(express.static('public')); app.get('/', function(req, res) { res.sendFile(__dirname + '/index.html'); }); wss.broadcast = function broadcast(data) { wss.clients.forEach(function each(client) { client.send(data); }); }; wss.on('connection', function(ws) { ws.on('message', function(msg) { data = JSON.parse(msg); if (data.message) wss.broadcast('<strong>' + data.name + '</strong>: ' + data.message); }); }); http.listen(3000, function() { console.log('listening on *:3000'); });
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
<!doctype html> <html> <head> <title>WebSocket Chat</title> <link rel="stylesheet" type="text/css" href="style.css"> <script src="http://code.jquery.com/jquery-3.0.0.slim.min.js"></script> </head> <body> <form> <div id="name-div"> <input id="name" name="name" autocomplete="off" autofocus placeholder="Enter your nickname" /> <button>Submit</button> </div> <div id="welcome"></div> <ul id="messages"></ul> <div id="input-div"> <input id="message" name="message" autocomplete="off" placeholder="Type your message here" /> <button>Send</button> </div> </form> <script> websocket = new WebSocket("ws://localhost:8080/"); $('form').submit(function() { name = $('#name').val() ? $('#name').val() : 'Anonymous'; $('#name-div').hide(); $('#welcome').text('Hello ' + name); websocket.send(JSON.stringify({ name: name, message: $('#message').val() })); $('#message').focus(); $('#message').val(''); return false; }); websocket.onmessage = function(evt) { $('#messages').append($('<li>').html(evt.data)); }; websocket.onerror = function(evt) { $('#messages').append($('<li>').text('<span style="color: red;">ERROR:</span> ' + evt.data)); }; </script> </body> </html>
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.
* { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } #name-div, #welcome { background: #AAA; padding: 10px; width: 100%; } #input-div { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; }
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