×
By the end of this chapter, you should be able to:
websocket
is HTTP
and WS
protocolssocket.io
One of the most popular libraries when working with Node is Socket.io, which is a library for handling websocket connections and communication between multiple clients and servers. There is a built-in module for Node for websockets, but the Socket.io library abstracts quite a bit of detail for us, making it setup much more straightforward. But first, let's try to understand what a websocket is.
With the HTTP protocol, a client and server communicate via the request-response cycle. The client initiates a request, the server issues a response, and the cycle is complete. When that interaction is over, the connection between client and server is complete (though the connection can be kept alive via HTTP headers).
With WebSockets, clients and servers connect through a process called a "handshake" and then keep the communication open, which allows for bidirectional communications: the client can push data to the server, but the server can also push data to the client without first waiting for a request to come in! This allows for applications that feel as though they are updating and responding to user input in real time. Chat rooms and multiplayer games are both examples of applications that can benefit from using websockets.
The ws
or websocket protocol is an upgrade from another strategy known as "longpolling," which involves making frequent AJAX calls to see if the server has any new information and then updating the client accordingly.
You can read more about Socket.io here. Let's get started with a simple application.
mkdir learn_socket_io && cd learn_socket_io touch app.js npm init -y npm install --save express socket.io mkdir views touch views/index.html
Here is what our app.js
looks like:
var app = require('express')(); var server = require('http').createServer(); var options = { cors: true, origins: ["http://127.0.0.1:4300"] }; var io = require('socket.io')(server, options); io.on('connection', function(socket){ console.log("connection!"); io.sockets.emit('from server', 'HELLO!'); socket.on('from client', function(data){ console.log(data); }); }); http.listen(3000, function(){ console.log('listening on localhost:3000'); });
The most important part of the code is what's happening inside of the io.on
. Fundamentally, websocket connections in socket.io
are responsible for two things: emitting events using the emit
method, and listening for emitted events using the on
method. These two methods are the foundation of communciation in socket.io
.
Here, we're saying that whenever a client connects to a server, we should create a websocket connection, and then that connection should emit an event called "from server" along with a message of "HELLO!".
We're also setting listeners on the server for events from clients. When a client emits an event called "from client", the server should take the data from that event and log it to the terminal.
In order to get our application working, we next need to set up some code on the client to create the websocket connection, emit events, and listen for emitted events. Here's our index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>First Socket.io application</title> </head> <body> <script src="/socket.io/socket.io.js"></script> <script> var socket = io('localhost:3000'); socket.on('from server', function (data) { console.log(data); socket.emit('from client', 'WORLD!'); }); </script> </body> </html>
Let's step through the sequence of events when this page loads:
var socket = io('localhost:3000')
).'conncection'
event. In our application, this causes the server to send to all connected websockets a 'from server'
event, with a message of 'HELLO!'
.'from server'
events. When it receives such a request, it console lots the data, then emits its own event, called 'from client'
, with data of 'WORLD!'
.'from client'
event, it logs the corresponding data to the terminal.One thing to note is that when a client connects, the 'from server'
event gets emitted to all websocket connections (we emit on io.sockets
, not socket
). You can verify that all clients receive the event by going to localhost:4300
(as the address that we pass into http-server
, and that we registered as an accepatable cross origin that can access the socket when configuring options
object on the server), on two separate tabs. The first tab should have 'HELLO!'
logged twice: once when it connected to the server, and once when the other tab connected!
For another example using Socket.io, check out the chat room tutorial in their documentation.
When using Socket.io, there are different types of messages you may want to send to different users. For managing chat rooms, socket.io
has the idea of a room
which has its own name and each socket has its own id
to ensure private messages can work.
Here are the helpful methods for sending certain types of messages to certain users:
io.emit('name of event');
or io.sockets.emit('name of event');
- sends to everyone in every room, including the sender
io.to('name of room').emit('name of event');
- sends to everyone including the sender, in a room (the first parameter to to
)
socket.broadcast.to('name of room').emit('name of event');
- sends to everyone except the sender in a room (the first parameter to to
)
socket.emit('name of event')
- sends to the sender and no one else
socket.broadcast.to(someOtherSocket.id).emit();
- Send to specific socket only (used for private chat)
You can see a small chat example with socket.io here.
When you're ready, move on to Sending Email with Nodemailer