This mini-project shows how to implement a simple web browser chat utilizing websockets technology for bi-directional client to server communication.
We are using node.js
, express
and socket.io
for the implementation.
Here is a live coding session that shows how it can be done.
Duration: 4:08 (coding - 3:51)
Disclaimer: never use this code in production. It was created for fun.
Let's break down the solution and comment on some complex or interesting things.
0:13 - initialization of the project. Every node.js
-based project starts with package.json
file that contains all dependencies, run scripts and many more. npm init -y
command just creates minimal package.json
file inside current folder.
0:19 - installing dependencies. For the project we need only 2 of them - express
and socket.io
. Using --save
parameter to make sure that these dependencies find their place in package.json
. After this step package.json
should look like this:
{ "name": "webchat", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", "socket.io": "^4.3.0" } }Note that the versions might differ - new versions are released quite frequently.
0:33 - building basic HTML template.
0:45 - starting work on server side. We will be using express
as a framework for building the web server.
On this step the server does not do anything much than just serving the static content from the current folder.
The server will be running on port 3000
- there is no specific logic behind this port number. But somehow it's popular withing express
world.
1:07 - run the server with node index.js
. Our project is very simple and does not require any build or assembly pipeline. Server is only one file that can be run directly by node.js
engine.
In more complex scenarios the run script should be described inside package.json
.
Exprected result at this step - web server running on port 3000
serves static content (index.html
file) from current folder.
1:15 - adding layout to HTML page. The UI is very simple and minimalistic. It will contain single input field for chat message, "Send" button and an area for the received messages. No formatting, no styles, no emoji - just plain HTML page.
1:30 - activating websockets on the server side. For this we use socket.io
that can hook up to existing express
server.
socket.io
is an event-based framework - we'll write code that reacts to certain events. For the start we are interested in handling of new connections - when a new client opens a websocket connection to the server.
Note that we can use socket
parameter of connection
event later on - it represents the particular client.
1:50 - switching back to the web page development. We need to use the websockets client in the HTML page. Easiest way is to use the client that comes with server-side socket.io
.
In the beginning we ran npm i --save express socket.io
command that downloaded required dependencies and stored them in node_modules
folder. Here we are cutting the corner and just using a client from locally installed package.
In real life the websockets client should be separated and stored locally next to the client.
1:57 - initialization code for websockets client. Just create socket.io
client and that's all for the minimalistic setup.
Also for fun let's make every client unique and assign every brower client a random name.
Here we handle successful connection as well - once the connection is established we can communicate with the server. In our case we just notifying the server that new user has joined.
Right now there is nothing on the backed related to new client's joining - but we'll address it a bit later.
But already now (after browser refresh) we see messages in server console that new client is there.
2:22 - the remaining part for the frontend is sending and receiving messages. Here we need to work with a couple of HTML elements:
onsubmit
event. It will be triggered when one presses "Send" button.onsubmit
event handler to the form
. Notice that we are doing e.preventDefault();
not to propagate submit event - otherwise it will be considered as POST
action on the page and the browser window will be reloaded.
socket.emit
call - later it will be handled on server side.
socket.on
. The callback function will be called every time when new message arrives.
<b>bold text goes here</b>
. The received message will be rendered with HTML formatting.
3:05 - finishing off with server side implementation. We need to handle these scenarios:
joined
event when the websocket connection is established. We need to handle this event using socket.on
to receive user name.
io.emit
. Notice that if we do socket.emit
then the message will be send only to current user, not to everyone.
io.emit
This concludes this mini-project. It looks very simple due to power of used libraries (express
and socket.io
) as they hide all complexity.
Sources: https://github.com/5minute/examples/tree/main/webchat