socket.io allows us to make a connection between a client and a server but have that connection persist.
Normally, the client and server would have a simple transaction: the client would get data from the server then close the connection. If the client needs 10 pieces of information they have to make 10 requests. With WebSockets, the client can connect to the server and have that connection stay open. So the client can make 10 requests with just 1 connection.
Socket.IO is composed of two parts:
- A server that integrates with (or mounts on) the Node.JS HTTP Server
- A client library that loads on the browser side
Set up Socket.io on Express Server
Install dependencies: The only packages you need are Express and Socket.io
npm install express socket.io
Import packages
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
Create io object
const app = express();
const server = http.createServer(app);
const io = socketio(server);
http.createServer
is used by Express under the hood but we need to access it directly
Socket.io Methods on the Server
This is a function that runs every time a client connects to our server. In the callback, we create a socket instance for each one of the clients
We can access the socket.id
, a random ID that is automatically assigned to them when they join the server.
// Run when client connects
io.on('connection', socket => {
console.log('New WS Connection...');
});
socket.on
listens for events from the client
The string "sendMessage"
is a custom event emitted from the client whenever a new message is sent. socket.on
allows us to access that event and any data sent with it (message
) on the server.
socket.on("sendMessage", message => {
console.log(message)
})
io.emit
sends an event down to every client connected to the server
In this example, we are taking the message that was sent to the server with "sendMessage"
and emitting it to all the connected sockets through an event called "recieveMessage"
.
socket.on("sendMessage", message => {
io.emit("recieveMessage", message)
})
In order to send a message to every socket except the socket sending the message, use socket.broadcast.emit
socket.broadcast.emit("recieveMessage", message)
Emit message to a room with socket.to
in front of the emit
command
socket.on("sendMessage", (message, room) => {
socket.to(room).emit("receiveMessage", message)
})
To join a room, use the socket.join method. You can only join a room from the server, not the client.
socket.on("joinRoom", room => {
socket.join(room)
})
Send a callback function to the server.
On the client, pass the callback function as the last parameter.
socket.emit("joinRoom", room, message => {
displayMessage(message)
})
On the server, use the callback function. Basically, you’re doing this: displayMessage(`Joined ${room}`)
socket.on("joinRoom", (room, cb) => {
socket.join(room)
cb(`Joined ${room}`)
})
Disconnect from the server
socket.on('disconnect', () => {
//...
});
Socket.io on the Client
In this tutorial, we are assuming you are using static HTML pages as the frontend. So no JavaScript frameworks like React or Vue.
If Socket.io is installed in the root directory, you can use the client library in our public files by simply adding this line to your main HTML file
<script src="/socket.io/socket.io.js"></script>
You can create a Socket object with this command:
const socket = io()
If Socket.io is NOT installed in the root directory, you must install the socket.io-client package in your client folder.
npm i socket.io-client
Then, in a JavaScript file you can import io
from the library
import { io } from 'socket.io-client'
Then, create a socket on the frontend by calling the io function and passing in the address of the server.
const socket = io('http://localhost:3000')
Also, on the server, make sure you add the following parameters to the require('socket.io')
function. This will prevent CORS from blocking the frontend from connecting to the backend. The URL should be the URL that your frontend application is running on.
const io = socketio(server, {
cors: {
origin: ['http://localhost:8080']
}
});
Use socket.on to receive events from the server
// Receive message from server and output it to screen
socket.on('message', (message) => {
outputMessage(message);
});
// Example 2
socket.on('roomUsers', ({ room, users }) => {
outputRoomName(room);
outputUsers(users);
});
Use socket.emit to send events to the server
// Tell server you want to join a chatroom
socket.emit('joinRoom', { username, room });