Introduction
In modern web development, data exchange between clients and servers forms the backbone of the online world. Whether fetching data to construct the webpage, submitting forms, or live streaming, client-server interaction is crucial for developers to build robust and efficient web solutions. In this blog, we dive into fundamental concepts behind client-server interactions, mainly focusing on Serve-Sent Events and how they have added value to a real-time, ongoing project.
Client-Server Architectures / Interaction Approaches
Some of the well-known client-server architectures/ interaction approaches are:
- Request-Response: This is the most common type of interaction, where the client sends a request to the server, and the server process the requests. A well-known protocol for this type of interaction is RESTful services.
- Publish-Subscribe (Pub/Sub): In this model, clients subscribe to topics or channels, and the server publishes messages to these topics. Clients receive messages from the server whenever there's new data or an event occurs. Examples include WebSocket, MQTT, and Server-Sent Events.
- GraphQL Queries: GraphQL is a query language that executes queries against a server's data. Clients can send queries for the required data, and the server responds precisely with the requested data structure. As a result, clients can retrieve only the data they need in a single request, improving efficiency and reducing over-fetching.
- File Transfer: Clients can upload or download files to or from the server, through direct HTTP requests or specialized protocols like FTP (File Transfer Protocol).
RESTful Interactions
Representational State Transfer (REST) is an architectural style that uses standard HTTP methods (GET, POST, PUT, DELETE) for communication between clients and servers. RESTful interactions typically involve accessing and manipulating resources using URIs (Uniform Resource Identifiers) and exchanging data in formats such as JSON or XML.
WebSocket
WebSocket provide full-duplex communication channels for a single, long-lived connection, offering real-time data exchange between the client and server. This is bi-directional communication and is useful for applications requiring continuous data updates or streams.
Server-Sent Events
The focus of this blog, Server-Sent Events (SSE), is a web API that enables servers to push events to web clients over a single HTTP connection. It is part of the HTML5 specification and is supported by most modern web browsers. It is simple and easy to use, without the complexity of WebSockets, making it the go-to option for developers.
Key Features of SSE
- One-directional Communication: SSE allows servers to send data to clients without requiring an additional request. This makes it ideal for scenarios where the server needs to push updates or notifications to the client in real time.
- Automatic Reconnection: The SSE connection automatically restarts during a network or server disruption, enhancing user connectivity.
- Event Streams and Event Types: The SSE supports the concept of event streams, where servers can categorize different events, and clients can subscribe to specific event types. This enables efficient event filtering and processing on the client side.
Communication Flow
- The client establishes the connection to the server’s SSE endpoint using the EventSource API.
- The server-side application maintains a loop that serves incoming SSE connections from clients.
- When an event occurs or data becomes available for transmission, the server-side application flushes the SSE message to connected clients over the established HTTP stream.
- On the client side, the EventSource object receives incoming messages and triggers event handlers to process ahead.
- Once the request is complete, the connection will be closed.
Case Study
Introduction to Application
The Azure cloud-based web application automates work scheduling for an energy utility client. The focus of the application was to make the work of the assigning manager easy. The application identifies the work and availability of the crew and lists assignment suggestions against each work. Once the suggestion list is generated, work assigning managers can review the work assignment, permits, and approve the crew assignment.
Block Diagram
Application Challenges
- Recursive API calling for time-taking APIs: The backend (.NET API) fetches data from other downstream systems. This takes time, and on top of the fetched records, the API performs complex logic adding additional seconds. The APIM will time out in 30 seconds; therefore, it is necessary to call the API from the FE application multiple times. We also need to maintain a flag to return the data once it is ready. Here, the FE needs to recursively call the APIs until it gets the data or flag is updated.
- Synchronizing real-time notification with repetitive API calling: Our application must write back into many other downstream applications, and we need to notify the users on recent data change and changes from other users. To be in sync, FE needs to do a recursive call even when there is no new notification.
The main problem from both above scenarios is recursive Api calling which will lead to other performance issue as these calls will consumes more network bandwidth and consumes server resources.
Challenges Resolved Using SSE
As SSE is a long-lived HTTP connection in both our problems it helps to create a channel between the client and server where the server keeps serving the initial request until the client closes the connection.
- No recursive API Calling for Time-Taking APIs: Once the server receives a GET request from the client, a channel is created between them. The server will accept the request and invoke a logic to gather the data from the lower system and process it. The status of this logic will be maintained in a flag. At every predefined time interval, the status will be checked. The flag indicates when the data is ready, and flushes result into the channel. Thus, there will be no need for recursive calls from the client side.
- Synchronizing Real-Time Notifications with Repetitive API-Calling: On application load, the request is sent to the server via SSE, and server will keep flushing notifications to the client as and when they are generated. There will be no repetitive API calls from the client side. The channel will be open as long as the application is live.
Implementation in Angular (client) .NET (Server)
SSE Implementation at the Client Side
- Create a new service file that maintains all the SSE operations.
- Create the URL that points to the proper endpoint.
- Import the EventSourcePolyfill if you must alter the request header like adding authorization header details, token etc.
- Extract the bearer token or other authorization details as per the need.
- Create a method to disconnect the connection once the request is served.
vi. This getEventStream() method can be invoked wherever required by passing the parameters. The unique key parameter helps to differentiate the events and helps disconnect the correct event stream.
vii. Every time, the data received from the server will be available in the subscribed method.
SSE Implementation at the Server Side
- Create a controller and add an action method to respond to the event.
- Take CancellationToken as a parameter to interrupt the loop any time needed.
- We can add any other logic to the loop that helps decide when to stop the loop and exit the method.
- Add a logic to construct the data.
- SSE accepts the message in string format, so, serialize the data and keep flushing every time the data is constructed.
Conclusion
In conclusion, Server-Sent Events (SSE) provide a powerful mechanism for enabling real-time communication between clients and servers over HTTP. Through a simple and standardized protocol, SSE allows servers to push updates to clients in an efficient, reliable, and scalable manner, making it ideal for applications requiring real-time data updates, such as live feeds, notifications, and dashboards.
Author Bio
- Name: Nagasharath D R
- Position At Encora: Senior Software Engineer
- Experience: 8y 4months
- LinkedIn Profile: https://www.linkedin.com/in/nagasharath-d-r