Socket.IO is an open-source, cross-platform library that provides full-duplex bidirectional communication between a client and a server based on events. It is built on the WebSocket protocol, providing additional capabilities such as automatic reconnection and fallback to HTTP long polling where WebSockets cannot be used.
Yes, Socket.IO is a good choice for building real-time web applications as it offers many features out of the box that will be useful for developers, including:
Room and namespace support allows you to group clients into rooms who can all receive broadcast or multicast messages.
Automatic reconnection means you don’t have to worry about clients when they go online or offline.
Binary data support, allowing you to exchange more than just chat messages, including images or other media.
Socket.IO is not an API in the traditional sense. It is a library or framework that abstracts away the underlying transport mechanism and provides a set of tools and utilities for building real-time, bidirectional communication between a client and server.
Socket.IO comprises both a client and server component, each exposing its APIs.
Socket.IO can use TCP and UDP as the underlying transport protocol, but it primarily uses TCP.
TCP (Transmission Control Protocol) is a reliable, connection-oriented protocol that ensures data is delivered in order and without errors.
On the other hand, UDP (User Datagram Protocol) is a connectionless, unreliable protocol that sends data without checking if it was received successfully.
UDP is more lightweight than TCP since only the latter establishes a connection between client and server, but it can only be used by applications resilient against missed messages.
While Socket.IO is explicitly not a WebSocket implementation, there are several similarities. Both are event-based, meaning you would ‘listen’ for events like connect, disconnect, or new_message, and both allow you to send structured data like JSON objects.
You can think of Socket.IO as an abstraction layer on top of the underlying transport protocol. As well as the underlying communication layer, the library implements additional features such as automatic reconnection, packet buffering, and message acknowledgment and falling back to HTTP long-polling if WebSockets are unavailable, adding robustness.
Socket.io Server Example:
Socket.io Client Example:
The library supports two transportation methods: HTTP long-polling and WebSockets. The HTTP long-poll connection is established first and then upgraded to a WebSocket connection if possible. WebSockets cannot run everywhere, for example, they are blocked by many corporate proxies and firewalls, therefore the HTTP long-poll is initiated first since it is more likely to succeed. After the HTTP long-poll connection is established, it is ‘upgraded’ to a WebSocket connection in a process that is entirely transparent to the end user.
Socket.IO consists of two distinct layers, present on both the client and server:
The low-level plumbing is provided by a separate library called Engine.IO
The high-level API which is provided by Socket.IO
As a developer or user, you would not typically interface directly with Engine.IO but this is running behind the scenes to establish the connection, negotiate a transport mechanism and detect any disconnects. When comparing Engine.IO with WebSockets the two are functionally very similar, only Engine.IO provides an abstraction layer allowing you to migrate from a HTTP long-polling connection without (crucially) losing any messages.
The high-level Socket.IO API adds some noteworthy features on top of the basic connectivity provided by Engine.IO:
Buffered events allow you to send events when not connected that will be delivered when the client reconnects. This can lead to spikes in traffic if the client takes a long time to reconnect so you need to code your client accordingly.
Acknowledgments allow you to specify a callback which will be invoked when the other side acknowledges the message has been received.
Broadcasting and multicasting (a concept Socket.IO refers to as Rooms) allow a server to send a message to multiple clients, though a client can't broadcast to other clients.
As with any solution that involves listening for and sending messages the biggest challenge is how to scale beyond a few thousand users.
Socket.IO is a library, it is NOT an infrastructure. As a solution architect or developer, you are responsible for deciding how your solution will reliably scale which is going to involve using multiple server nodes and load-balancing client connections between them. Load balancing comes with its own set of challenges but since Socket.io has been around for over a decade the community has come up with a robust set of best practices, for example, the concept of Adapters allows you to send a broadcast message between clients connected to different servers using a Pub/Sub mechanism.
Still, even though solutions do exist to scale Socket.IO, a lot of consideration is required by your development team and it is very difficult to consider every edge case.
Suggested architecture for broadcasting messages across server instances with Socket.IO:
In contrast, PubNub provides a highly-scalable, low-latency messaging solution for teams looking to reach production quickly. Sign up for a free trial and get up to 200 MAUs or 1M total transactions per month included.