This article talks about a popular open-source library called “Socket.IO”. It’s often used to build real-time web applications, like multi-player games and co-editing, co-creation applications.
It explores the relationship between WebSocket API, Socket.IO library and an Azure service.
- WebSocket API – provides the transport-level plumbing of bi-directional communication between clients and server.
- Socket.IO library – builds on top of WebSocket API and provides application-level features that are common when developing real-time web apps.
- Azure Web PubSub for Socket.IO – a feature from an Azure service that provides the infrastructure for massive scalability of Socket.IO apps.
What is WebSocket API?
WebSocket API allows web apps to establish a persistent, bi-directional communication channel between the server and client. Compared with polling techniques based on HTTP, WebSocket consumes less resources and offers lower latency. When we conducted performance test between using HTTP polling-based technique and using WebSocket, we saw a 10x reduction of memory reusage.
Screenshot take from caniuse.com/?search=websocket
WebSocket is a perfect fit for building real-time web experiences. It’s why it was introduced in the first place. But the API only concerns itself with establishing the communication channel, in other words, it’s an API that works at the transport level. Application developers much prefer working at a higher level, a level that brings them closer to the application they are building.
The application-level questions developers grapple with are of these sorts:
- How do I send a notification to every online user when the database is updated?
- How do I notify the only the users who are interested in a certain company stock?
- How do I make sure the moves made by one game player are delivered to other players quickly?
What is Socket.IO library?
Socket.IO is a popular open-source library for building real-time web experiences. When we conducted a user study earlier this year, we were pleasantly surprised to learn that developers use Socket.IO for all kinds of applications, from the typical chat rooms and multi-player games to as far afield as controlling IoT devices and real-time monitoring for fraud detections.
While developers don’t necessarily need to use Socket.IO library to build real-time web experiences as these days browsers have solid support for WebSocket API, they continue to choose Socket.IO for several reasons.
Developers choose Socket.IO for productivity gains
The gain in productivity is why developers choose Socket.IO. Socket.IO removes the need to focus on transport level concerns. It offers higher-level APIs to manage client connections as a group. We can easily add a client to a group and send messages to all the clients in that group.
// Sends a message to all the clients in the room ‘room-101’. The event name is “greeting” and the message content is "Hello. Hola! 你好. ");
io.to("room-101").emit("greeting", "Hello. Hola! 你好. ");
Group membership is highly dynamic in nature. We can add and remove a client from a group as we see fit. As needs arise, we may have many groups, and a client can be in multiple groups.
// Adds a single client to “room-101”
io.in(theSocketId).socketsJoin("room-101");
Besides these high-level APIs, Socket.IO handles reconnect when connection drops which is common due to the nature of network connectivity.
Easy-to-learn and easy-to-use APIs
Another selling point is the design of the APIs. Server-side APIs mirror the client-side APIs so once developers become comfortable with one side of the APIs, they can easily transfer the knowledge to the other side. And it conforms to the event-based nature of the browser. Developers can define event handlers to whatever event names they define. It’s been shared with us by numerous Socket.IO users that APIs are intuitive and easy to use.
// Client defines an event handler to handle an event named “greeting”
socket.io.on("greeting", () => {
// ...
});
To learn more about Socket.IO, visit its documentation site.
Using a high-level library like Socket.IO is not without challenges. Azure solves the scalability challenge.
It’s hard to find faults in Socket.IO as a library that abstracts away the common tasks of building real-time web experiences. Developers can hit the ground running without a problem. That’s until real users start using the applications. For one, meeting the challenge of thousands+ online users can be a pain and an unfamiliar territory for developers. It’s entirely doable and there are guides on the internet, just that it’s difficult to set up. When we are on a deadline to ship features reliably, the lines of code needed to build the infrastructure eat away the already tight time budget.
When we surveyed Socket.IO users, scaling out Socket.IO servers came up the top of the challenges. Scaling out refers to the practice of setting up more than one Socket.IO server and instrumenting a mechanism to coordinate messaging between Socket.IO servers. Plain as it sounds, the devils are in the implementation details.
This is an area Azure can add much value. We asked ourselves “how to make scalability a non-issue for developers” and “how to provide the simplest developer interface” to developers familiar with Socket.IO library?
With the input from the Socket.IO community (over 200 responses), we brought native support for Socket.IO on Azure. This means developers can continue using the Socket.IO APIs they know and love and let Azure handle scalability. You can follow the quickstarts to see how easy it is port a locally running Socket.IO app to Azure. Once it’s running on Azure, it’s ready to handle up to 100,000 concurrent connections with on single Azure resource.