Have you ever played a multiplayer online game where the scoreboard was getting updated in real-time? If you have, then you know that players don’t need to reload the game to view the score. In this case, the connection between the server and the client is kept open and both of them are in continuous communication.
This type of connection is called full-duplex, where both the parties involved in communication can send and receive messages simultaneously.
These types of connections on the web are made using web sockets. You can also set up a timer that will send a request to the server from time to time, but this is not ideal for real-time data.
The client sends an HTTP request to the server to open a connection. The request looks like this.
GET ws://some-url HTTP/1.1
Connection: Upgrade
Upgrade: websocket
If the server agrees to the connection then it responds with a 101 switching protocols response. At this point, the handshake is complete and the TCP/IP connection is made and left open to allow a bidirectional connection to stay functional. It will remain open until one of the parties drops off.
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
In this article, we will first implement a socket without using any third-party library like Socket.io to get the full idea of how sockets work.
Set up an empty folder and run npm init to initialize a new node project and install ws using npm i ws.
Create two folders, server and client. We will use these two folders to separate our client and server code. My directory looks like this.
Create index.js inside of the server folder and write the following code.
1 2 3 4
const webSocket = require('ws'); const server = new webSocket.Server({ port: '3000' });
We have instantiated a ws object with the name webSocket. The next line is creating the socket server on the localhost:3000.
Now we will create a connection, and on successful creation, we will get a socket object in the javascript callback.
1 2 3
server.on('connection', socket => { })
With this initial handshake, there are two things we can do here. Listen for the incoming messages from the client, which will be handled in callback, or we can send a message back to the client. The following code depicts that.
1 2 3 4 5 6
server.on('connection', socket => { socket.on('message', message => { socket.send(`Hello {message}`); }) })
In the end, your server/index.js should look like this.
1 2 3 4 5 6 7 8 9 10 11
const webSocket = require('ws'); const server = new webSocket.Server({ port: '3000' }); server.on('connection', socket => { socket.on('message', message => { socket.send(`Hello {message}`); }) })
Now our socket is set up on the server-side, let’s write the client-side code to use the socket. Create a file in the client folder, client/app.js.
The client-side code will have a built-in web-socket class which will be instantiated with the address of the server, but using the ws:// protocol instead of HTTP. This will automatically trigger the handshake to open the connection, which we then can listen to, and just like on the server we can use the socket to both listen to and send the messages.
To send a message we use the socket.send() function. We will create an HTML file to trigger this function.
In order to receive a message, we use socket.onmessage() function, as follows.
1 2 3 4 5
socket.onmessage = ({ data }) => { console.log(`Message from server {data}`); }
We are here printing the data that is sent by the server in response. In the end, your app.js file should look like this.
1
2
3
4
5
6
7
8
9
10
11
const socket = new WebSocket('ws://localhost:3000');
socket.onmessage = ({
data
}) => {
console.log(`Message from server {data}`);
}
document.querySelector('button')
.onclick = (bt) => {
const msg = document.querySelector('input');
socket.send(msg.value)
}
Let’s create an HTML file in the same folder to finish our task.
1 2 3 4 5 6 7 8 9 10 11 12 13
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script defer src="app.js"></script> </head> <body> <input placeholder="Enter your name"> <button>Send</button> </body> </html>
Our HTML file has a simple input field and a button to trigger our app.js file. Make sure to require the javascript file.
Now, let’s check how this performs. Open the HTML file in the browser and open your console, in the side.
Whenever you type in your name and hit send you receive a message as shown on the right side in the image. Notice that whenever you make this request the page does not reload and it’s a continuous and open connection.
This was a very basic implementation of socket, but a necessary one to know how sockets really work.
The server that we created cannot broadcast this message to multiple users like in a group chat. Doing this without any third party library will be really tough. This is where high level libraries like socket.io come forward.
This was an introduction to web-sockets.
Good Bye✌