Getting Started With Node SocketIO

4 minute read

WebSocket

What are websockets?

  • Communication between a client(browser) and server
  • Bidirectional (data flows both ways)
  • Allows real-time data flow

Allows real time communication such as chat rooms between multiple clients.

Applications for websocket?

  • Multiple browser games
  • Chat rooms
  • Colloborative code editing
  • Live text for sports/news website
  • Online drawing canvas
  • Real-Time to-do apps with multi users

Dependencies:

  1. Node
  2. Express
  3. socket.io

Client and server side code

socket.io requires both client and server side code for them to communicate.

Below is a server side code

const express = require('express')
const socketio = require('socket.io')

const app = express()
const server = http.createServer(app)

const io = socketio(server)
const port = process.env.PORT || 3000


let count = 0


// Whenever a new connection gets fired, io.on('connection'..) gets executed. 
io.on('connection',(socket) => {
    console.log("New WebSocket Connection.")
/*
Send data to a particular connection. Since a new client
was connected, we don't need to send current count to all connections. Just to the one that is recently connected. 
*/
    socket.emit('countUpdated', count)

    socket.on('increment', () => {
        count++
/*
socket.emit() : will emit to a particular connection
io.emit(): will emit to all the connections that's avaliable
*/
        io.emit('countUpdated',count)
    })
})

server.listen(port, () =>{
    console.log(`Server is up on port ${port}`)
})

Client Code

index.html

<script src="/socket.io/socket.io.js"></script>
<script src="/js/chat.js"></script>
<button id="increment"> +1 </button>

chat.js

// This will connect to our server
const socket = io()

socket.on('countUpdated', (count)=>{
    console.log('The count has been updated', count)

})


document.querySelector('#increment').addEventListener('click', () => {
    console.log('clicked')
    socket.emit('increment')
})

Commonly used methods

Receive Data

  • socket.on(eventName, callback)

socket.on(), is used to receive data

Parameters:

  • eventName (String)
  • callback (Function)
  • Returns Socket

Register a new handler for the given event. Used more to receive data.

socket.on('news', (data) => {
  console.log(data);
});
// with several arguments
socket.on('news', (arg1, arg2, arg3) => {
  // ...
});
// or with acknowledgement
socket.on('news', (data, callback) => {
  callback(0);
});

Send Data to a Connection

  • socket.emit(eventName[, …args][, ack])

socket.emit(), is used to send data to a particular connection

Parameters:

  • eventName (String)
  • args
  • ack (Function)
  • Returns Socket

Emits (dends) an event to the socket identified by the string name. Any other parameters can be included. All serializable datastructures are supported, including Buffer.

The ack argument is optional and will be called with the server answer.

Used to send data

const socketio = require('socket.io')
const app = express()
const server = http.createServer(app)
const io = socketio(server)

io.on('connection',(socket) => {
    socket.emit('event','message')
})

Send data to call connections

Send data to all connections including the socket that starts it.

const socketio = require('socket.io')
const app = express()
const server = http.createServer(app)
const io = socketio(server)

io.on('connection',(socket) => {
    io.emit('event','message')
})

Broadcast Data

Broadcasting means sending a message to everyone else except for the socket that starts it. More Info

  • socket.broadcast.emit(eventName, data)
const socketio = require('socket.io')
const app = express()
const server = http.createServer(app)
const io = socketio(server)

io.on('connection',(socket) => {
    console.log("New WebSocket Connection.")
    socket.broadcast.emit('message', 'A new user has joined!')
})

Detect if a socket (client) is closed

Inorder to detect a client has left a connection or also knows as if a socket is closed.

  • socket.on(‘disconnect’,callback) ``` js const socketio = require(‘socket.io’) const app = express() const server = http.createServer(app) const io = socketio(server)

io.on(‘connection’,(socket) => { socket.on(‘disconnect’,() => { io.emit(‘message’,’A user has left!’) }) })



## Data Acknowledgements

When we send data from client to server or vice-versa, we can also choose to have an ack, stating we have received the data.

**Client**
``` js
const socket = io()

socket.emit('sendMessage', message, (ack) => {
    console.log('The message was delivered!', ack)
})

Server

io.on('connection',(socket) => {
    socket.on('sendMessage', (message, callback) => {
            // Send received message to all users
            io.emit('message',message)

            // What we want to send back as ack
            callback('Delivered') 
    })
}

Socket Unique ID

A unique identifier for the session, that comes from the underlying Client.

io.on('connection',(socket) => {
    console.log(socket.id)
}

Namespaces

Socket.IO allows you to “namespace” your sockets, which essentially means assigning different endpoints or paths.

This is a useful feature to minimize the number of resources (TCP connections) and at the same time separate concerns within your application by introducing separation between communication channels.

Important note: The namespace is an implementation detail of the Socket.IO protocol, and is not related to the actual URL of the underlying transport, which defaults to /socket.io/….

For More Info About Namespaces and Rooms

Rooms

Within each namespace, you can also define arbitrary channels that sockets can join and leave.

Joining and leaving

You can call join to subscribe the socket to a given channel:

io.on('connection', function(socket){
  socket.join('some room');
});

And then simply use to or in (they are the same) when broadcasting or emitting:

io.to('some room').emit('some event');

To leave a channel you call leave in the same fashion as join. Both methods are asynchronous and accept a callback argument.

Emit and Broadcast Data in a Room

  • io.to.emit(): Send data to everyone in a specific room ``` js

* socket.broadcast.to.emit: 
Send data to everyone in a specific room except the one sending it. 
``` js
socket.broadcast.to(room).emit('message', 'data to send')

Default room

Each Socket in Socket.IO is identified by a random, unguessable, unique identifier Socket#id. For your convenience, each socket automatically joins a room identified by its own id.

This makes it easy to broadcast messages to other sockets:

io.on('connection', function(socket){
  socket.on('say to someone', function(id, msg){
    socket.broadcast.to(id).emit('my message', msg);
  });
});

Disconnection

Upon disconnection, sockets leave all the channels they were part of automatically, and no special teardown is needed on your part.

Tags:

Updated: