In applications, typical communication with the server is one-way: A client initiates a request to the server, the server performs the task, and the response is sent to the client.
However, it is also possible to write server-side code that communicates with the client in real-time, enabling two-way communication. This can be done with the help of SignalR — a library developed by Microsoft. This library is simple, powerful, and intuitive, often used to add real-time functionality to web and mobile apps.
At IntelliSoft, we have more than 15 years of experience in web app development, so we are more than familiar with this powerful library, and we’re thrilled to introduce you to it! In this SignalR tutorial, we’ll cover the essence of the library, its core data transport methods, main features, concepts, and limitations, so read on.
Table of Contents
What is SignalR?
SignalR is an innovative library developed by Microsoft to seamlessly incorporate real-time functionality into applications. This powerful tool empowers server code to effortlessly deliver content to clients in real-time, eliminating the need for clients to constantly request new data. Moreover, SignalR enables clients to effortlessly send messages to the server, fostering an interactive and dynamic user experience.
The History of SignalR
Before jumping into the world of the library’s characteristics, let’s go back in time a bit. This open-source library was created in 2011 and brought into the ASP.NET project, and released as its part in 2013.
Back then, it was challenging to achieve real-time messaging, mainly because developers used technologies like AJAX polling and long-polling, as well as server-sent events that weren’t implemented by browsers. Fortunately, SignalR solved this problem by providing real-time capabilities on the ASP.NET stack. SignalR created server- and client-side libraries, making the process easier.
When the library was created, most apps used jQuery, so SignalR JavaScript also depended on it. Before browsers adopted the WebSocket protocol, SignalR was responsible for all the processes, and how it managed real-time messaging was far from straightforward.
In 2018, jQuery got replaced with front-end frameworks such as Angular, React, and Vue, and WebSocket was finally available in all major browsers. In 2018 that SignalR, as we know it now, emerged, using WebSocket transport to establish a genuine two-way connection.
How Does SignalR Work?
When it comes to understanding how SignalR operates, the process begins with a client sending a request to the server. The SignalR library handles this request and determines the appropriate transport method for communication. Ideally, if both the server and client support WebSocket, it is utilized as the primary transfer method due to its efficient and low-latency nature.
However, there are scenarios where WebSocket support may be absent either on the server or the client side. In such cases, SignalR falls back to alternative transport methods to ensure uninterrupted communication. SignalR provides a range of fallback options, including Server-Sent Events (SSE) and Long Polling. These transport methods act as alternatives to WebSocket, enabling reliable data transfer even when WebSocket is not available.
SignalR Main Data Transport Methods
There are three main transport methods: WebSocket, Server-Sent Events, and Long Polling. The default way of choosing the perfect method is by going through all of them and establishing a connection through this method. Most modern browsers support WebSocket, so it’s the preferred method in most cases.
What is WebSocket?
WebSocket is a real-time technology enabling communication between client and server over a single-socket connection.
Working with WebSockets covers these steps:
- Establishing a WebSocket Connection: The initial step in establishing a WebSocket connection is the opening handshake, which involves a request/response exchange between the server and client. This handshake process varies depending on whether the client or server initiates it. WebSocket connections are established using the ws (WebSocket) or wss (WebSocket Secure/SSL) URI schemes. When all necessary conditions are met, the connection becomes secure and transitions into a ws connection.
- Efficient Data Transmission: Once the handshake is successfully completed, the client and server can exchange messages in real-time. These messages can contain either plain text strings or binary data, allowing for versatile data transmission between the two endpoints.
- Connection Closure: When the persistent connection has served its purpose and needs to be terminated, the server and client engage in a final handshake by sending a closing message. This process ensures a controlled and orderly closure of the connection, enabling both parties to conclude their communication effectively.
How Do Server-Sent Events Work?
SSE is a part of the HTML5 specification and is supported by all modern browsers. Unlike WebSocket, which supports two-way communication, SSE supports a one-way type of communication. Here, the server sends messages to the client, but the client can’t send any messages back.
In SSE, the data is sent as a series of events containing a message and an optional event type. The event type helps to see the differences between various messages and allows the client to handle them accordingly.
In this transport method, a client sends a request to the server, and the server responds to the client with an HTTP response with a MIME type “text/event-stream.”
The server’s response contains a series of events, all separated by a line character (“\n”). This is the usual format of an event:
- event: [event type]\n
- data: [message]\n\n
The first field names the event, while the second field contains the message.
How Does Long Polling Work?
If neither WebSocket nor SSE is supported, developers use long polling, and it can be considered a last resort. When the client makes a request, the server receives it and holds it until there is a change. As soon as there’s any change in the requested data, it returns to the client. Then, the client makes a request again.
Types of SignalR
ASP.NET SignalR
This is a library for ASP.NET developers. The first version was developed to help build real-time features such as apps for collaboration, dashboards, and live chats. This version is outdated, so developers are migrating to ASP.NET Core SignalR for future projects.
ASP.NET Core SignalR
This is the updated version of ASP.NET SignalR. It is now actively maintained and designed for building real-time web apps on the ASP.NET Core framework. This version offers developers improved performance, bug fixes, new features, and great scalability.
Azure SignalR Service
This is the cloud version of SignalR, provided by Microsoft as part of the Azure cloud platform. Its main goal is to simplify the deployment and management of real-time web apps. It offers high availability, automatic scaling, and real-time connection management.
Azure SignalR Service vs ASP. NET Core SignalR
Azure SignalR Service and ASP.NET Core SignalR are two powerful tools that offer similar essential functionalities, yet they possess distinct characteristics and deployment approaches.
ASP.NET Core SignalR provides flexibility in hosting options. It can be deployed on a server that supports ASP.NET Core or even as a self-hosted solution. However, when self-hosting, you bear the responsibility for ensuring scalability, maintenance, and security. This self-management aspect can consume significant time and financial resources.
On the other hand, Azure SignalR Service is a fully-managed product that builds upon ASP.NET Core. It relieves developers from the burdens of scalability and security management, as these aspects are inherently integrated into the service. Azure SignalR Service handles the scaling requirements transparently, allowing developers to focus on building their applications instead of worrying about infrastructure management.
Furthermore, the architectural differences between the two solutions are noteworthy. In the case of ASP.NET Core SignalR, the connection between the client and the server is direct. In contrast, Azure SignalR Service employs a negotiation process once the client establishes a connection with the service. This negotiation phase allows Azure SignalR Service to handle advanced features like broadcasting messages to multiple clients efficiently.
Regarding costs, ASP.NET Core SignalR is available for free, unlike Azure, which is a paid solution.
Related Readings:
- RabbitMQ vs Kafka: Choosing the Right Messaging System for Your Needs
- Angular vs React: pros, cons, and key differences
- What Threatens Your Web Application Security
- Node JS Advantages and Use Cases: Is This Environment Right for You?
- Flutter vs. React Native: Which to Choose for Cross-Platform Development?
Main SignalR features and concepts
Different types of SignalR have varying features and concepts, but the core features are the same for all versions. Let’s focus on them now.
SignalR hubs
A hub is the central server concept of SignalR. It got this name for a reason; the hub stores all the messages that arrive there before they are delivered to clients or used by the server. In short, hubs facilitate client-server communication.
To create a hub, you need two main things; a hub class and mapping.
First, you need to create a dedicated class that inherits from the Hub Class to create a hub.
For example, it may look like this:
Three different hub methods can be set with the following code snippets:
- SendMessage: sends a message to all connected clients
- SendMessageToCaller: sends a message to a caller
- SendMessageToGroup: sends a message to all clients in a specific group (Chat Users).
Hubs support two data formats: a binary protocol inspired by MessagePack and a JSON-based protocol. Usually, the JSON protocol is used by default. However, if you decide to use MessagePack, you must install the Microsoft.AspNetCore.SignalR.Protocols.MessagePack package.
SignalR client support
The solution supports multiple types of clients, including mobile and desktop apps, modern browsers, IoT devices, game consoles, etc. Moreover, it offers client SDKs targeting .NET, Java, and JavaScript.
Multi-protocol capabilities
This solution supports various transport protocols, including WebSockets (the most common), Server-Sent Events, and Long Polling. If the browser supports WebSockets, that is usually the transfer method of choice since it’s the fastest and most advanced option. However, if the browser does not support this protocol, SignalR chooses the one supported by the client and server. For instance, corporate networks often do not support WebSockets, so SignalR chooses SSE or long polling as a last resort.
Automatic reconnections
In the dynamic landscape of network connectivity, individuals frequently traverse between diverse devices and networks, encountering intermittent disruptions or momentary loss of connection. In response to this prevalent challenge, SignalR offers a remarkable capability, namely, automatic reconnection.
SignalR empowers applications to seamlessly reconnect to the server, irrespective of the device in use. By default, the client initiates up to four reconnection attempts, gracefully ceasing further attempts if all endeavors prove fruitless. However, this behavior can be finely tailored to meet specific requirements, enabling developers to customize the number of reconnection attempts as per their needs.
SignalR excels in accommodating a variety of messaging patterns. This versatile solution allows users to selectively send messages to a particular connection, disseminate information across all connected clients, or effortlessly dispatch messages to SignalR groups.
This flexibility in messaging patterns empowers developers to precisely shape their communication strategy based on the unique demands of their application.
SignalR service mode
SignalR offers versatile service modes to cater to different application requirements: Default, Serverless, and Classic.
In the Default mode, you leverage a web server application that acts as a host for the SignalR hub. SignalR acts as a proxy, facilitating seamless communication between the client and server. This mode shines when migrating to Azure, making it an ideal choice for those seeking a smooth transition to the Azure environment.
The Serverless mode, on the other hand, eliminates the need for a dedicated hub server. Instead, messages can be directly sent to clients using WebSockets or Azure SignalR Service data plane REST APIs. This mode proves advantageous when starting a new project as it allows developers to bypass the complexities associated with hub servers.
Lastly, the Classic mode represents a hybrid approach, combining elements from the previous modes. Primarily designed for applications created before the introduction of the other two modes, Classic mode may not be the most suitable option for new SignalR projects. As such, it is generally recommended to opt for the other modes unless specific legacy considerations warrant the use of Classic mode.
Scaling SignalR
Scaling SignalR effectively is an important consideration when working with ASP.NET Core.
While vertical scaling, which involves increasing the resources of a single server, may appear to be the straightforward choice, it may not be the most optimal solution for large-scale systems. In such cases, horizontal scaling emerges as the preferred approach.
Horizontal scaling entails adding multiple servers to distribute the load, making the system more robust and better suited for substantial projects. By horizontally scaling SignalR, you can handle increased traffic and ensure a reliable and responsive experience for your users.
If you prefer not to handle the hosting, scaling, and management of SignalR infrastructure yourself, Azure SignalR Service presents a convenient alternative to ASP.NET Core SignalR. By leveraging Azure SignalR Service, you can offload the operational complexities and enjoy the benefits of a fully managed and scalable SignalR solution. This allows you to focus more on your application logic and user experience while leaving the infrastructure management to Azure.
SignalR limitations
While SignalR is an immensely popular library embraced by developers worldwide, it’s essential to acknowledge that it is not without limitations. Understanding these limitations is crucial for making informed decisions in your development endeavors.
- Poor data integrity
One limitation to consider is the potential for poor data integrity. Data integrity ensures that messages are delivered in the correct order and without loss, which is often vital for reliable communication. Unfortunately, SignalR does not inherently guarantee complete data integrity.
If maintaining the precise order of message delivery is critical for your application, SignalR may not be the optimal solution. However, it is possible to enhance reliability by incorporating sequencing information into messages manually, although this would require additional implementation effort on your part.
By being aware of this limitation, you can assess whether the level of data integrity provided by SignalR aligns with the specific requirements and constraints of your project.
- Single-region design
SignalR is always running in only one region, which can lead to various problems. For example, it can lead to poor UX and increased latency caused by all traffic coming through the same region, so some users may experience this issue more than others.
Latency can also affect the UX of the app, making it complicated for people to use it and collaborate with each other.
Another problem caused by single-region design is that it’s difficult to ensure resiliency. For instance, when one instance fails, you can automatically switch to another available one, even in another region. However, you would need to do it yourself and set the right system typology for everything to work, which can take a lot of time, effort, and money.
- Service Uptime
Microsoft guarantees that SignalR Service will be available at least 99.95% of the time. This is the number of premium accounts. For non-premium users, the SLA is 99.9%, which accounts for almost 9 hours of annual downtime.
For some businesses, such downtime can be detrimental to their success. Healthcare institutions that use apps for connecting patients and doctors 24/7 cannot afford to have so many hours of downtime a year.
- Self-hosting is complex and expensive
If you decide to self-host the library, think twice. It’s a complicated process because you would have to do everything by yourself:
- Scale it
- Ensure that it is highly available and tolerant of fraud
- Manage all of its parts
It’s a daunting task if you have never dealt with it before, and will require a lot of money. Moreover, you need an experienced team of engineers with experience with SignalR.
- Only three client SDKs
Only three client SDKs are offered: Java, .NET, and JavaScript. Thus, you can’t use other languages to implement SignalR on the client side, and there are no client libraries for Python, PHP, GO, iOS, Flutter, etc.
Applications of SignalR
One of the most common examples of its use is a chat, but it’s definitely not the only one. Here’s what you can use SignalR for:
- Real-time user notifications
- High-frequency updates
- Dashboards with real-time charts
- Collaborative applications
- Games and entertainment apps
- Alerting mechanisms
Conclusion
Microsoft did a great job with SignalR. This library is elementary to use, it’s highly intuitive, and offers super powerful capabilities for developers. With SignaR, adding real-time functionality to web and mobile applications is a piece of cake. However, you should pay attention to its limitations and think twice about whether SignalR is a perfect fit for your business type and the project you’re working on. If you have been thinking about using this library but need help or a consultation, IntelliSoft is here to help you, so don’t hesitate to contact us.