Course contentsShow
← C#
Lesson 1459 of 1,90813. Real-time Communication with SignalRFree lesson

Implementing Message Acknowledgement Patterns

Develop application-level protocols to verify successful delivery of critical real-time updates.

In this lesson, you will learn how to design custom acknowledgement protocols to guarantee that critical real-time updates reach your SignalR clients despite the fire-and-forget nature of WebSocket messaging.

While SignalR provides a reliable connection, the standard Clients.All.SendAsync call is asynchronous and unidirectional; the server has no native way of knowing if the client actually processed the data. To build a robust system for critical updates (like financial transactions or status changes), you must implement an Application-Level Acknowledgement Pattern.

The Acknowledgement Loop

The pattern relies on a two-way handshake. When the server pushes a critical message, it includes a unique CorrelationId. The client must then invoke a specific "Ack" method on the Hub to confirm receipt.

// Server-side Hub Method
public async Task SendCriticalUpdate(UpdatePayload payload)
{
    payload.CorrelationId = Guid.NewGuid();
    // Track the pending message in a persistent store
    await _pendingStore.Save(payload.CorrelationId, payload);
    
    await Clients.Client(payload.TargetId).SendAsync("ReceiveCriticalUpdate", payload);
}

// Client-side SignalR method
connection.on("ReceiveCriticalUpdate", (payload) => {
    // Process the data...
    // Send acknowledgement back to server
    connection.invoke("AcknowledgeReceipt", payload.correlationId);
});

Handling Unreliability

Because networks fail, you must implement a "retry-with-timeout" mechanism. If the server’s _pendingStore still contains the CorrelationId after a predetermined threshold (e.g., 5 seconds), the server assumes the message was lost or the client failed to process it. The server can then either re-transmit the message or escalate the status to a failure log.

By requiring this round-trip confirmation, you transform a standard broadcast into a verified delivery stream. This pattern is essential for maintaining consistency between server-side state and client-side UI when the message payload is mission-critical.

Key Takeaway: Since SignalR does not natively track delivery status, you must implement a correlation-based acknowledgement loop where the client explicitly reports receipt of unique message identifiers back to the Hub, allowing the server to handle retries for unconfirmed data.