|
| 1 | +# Disconneting Clients |
| 2 | + |
| 3 | +There is an option to disconnect a client from server. The flow is based on responding with *204 No Content* status code to reconnect attempt. |
| 4 | + |
| 5 | +<center></center> |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +The client disconnect functionality requires registering two services, which are not registered by default. |
| 10 | + |
| 11 | +### Client Identifier Provider |
| 12 | + |
| 13 | +First is implementation of [`IServerSentEventsClientIdProvider`](../api/Lib.AspNetCore.ServerSentEvents.IServerSentEventsClientIdProvider.html), which responsibility is to provide an identifier for a client. This identifier should remain the same if client performs reconnect(s). There is no ready to use implementation of this provider, as the approach to this should strongly depend on context. Below is a sample cookie based implementation (which is certainly not sophisticated enough for production scenarios). |
| 14 | + |
| 15 | +```cs |
| 16 | +internal class CookieBasedServerSentEventsClientIdProvider : IServerSentEventsClientIdProvider |
| 17 | +{ |
| 18 | + private const string COOKIE_NAME = ".ServerSentEvents.Guid"; |
| 19 | + |
| 20 | + public Guid AcquireClientId(HttpContext context) |
| 21 | + { |
| 22 | + Guid clientId; |
| 23 | + |
| 24 | + string cookieValue = context.Request.Cookies[COOKIE_NAME]; |
| 25 | + if (String.IsNullOrWhiteSpace(cookieValue) || !Guid.TryParse(cookieValue, out clientId)) |
| 26 | + { |
| 27 | + clientId = Guid.NewGuid(); |
| 28 | + |
| 29 | + context.Response.Cookies.Append(COOKIE_NAME, clientId.ToString()); |
| 30 | + } |
| 31 | + |
| 32 | + return clientId; |
| 33 | + } |
| 34 | + |
| 35 | + public void ReleaseClientId(Guid clientId, HttpContext context) |
| 36 | + { |
| 37 | + context.Response.Cookies.Delete(COOKIE_NAME); |
| 38 | + } |
| 39 | +} |
| 40 | +``` |
| 41 | + |
| 42 | +There is a helper method which simplifies registering an implementation. |
| 43 | + |
| 44 | +```cs |
| 45 | +public class Startup |
| 46 | +{ |
| 47 | + ... |
| 48 | + |
| 49 | + public void ConfigureServices(IServiceCollection services) |
| 50 | + { |
| 51 | + services.AddServerSentEvents(); |
| 52 | + |
| 53 | + // Register cookie based clients identifier provider for Server Sent Events |
| 54 | + services.AddServerSentEventsClientIdProvider<CookieBasedServerSentEventsClientIdProvider>(); |
| 55 | + |
| 56 | + ... |
| 57 | + } |
| 58 | + |
| 59 | + ... |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +### "No Reconnect" Identifiers Store |
| 64 | + |
| 65 | +Second is implementation of [`IServerSentEventsNoReconnectClientsIdsStore`](../api/Lib.AspNetCore.ServerSentEvents.IServerSentEventsNoReconnectClientsIdsStore.html), which responsibility is to store identifiers which should not be allowed to reconnect. There are two ready to use implementations. First stores the identifiers in memory, while the second is backed by distributed cache. Both have ready to use methods to register them. |
| 66 | + |
| 67 | +```cs |
| 68 | +public class Startup |
| 69 | +{ |
| 70 | + ... |
| 71 | + |
| 72 | + public void ConfigureServices(IServiceCollection services) |
| 73 | + { |
| 74 | + services.AddServerSentEvents(); |
| 75 | + |
| 76 | + // Register cookie based clients identifier provider for Server Sent Events |
| 77 | + services.AddServerSentEventsClientIdProvider<CookieBasedServerSentEventsClientIdProvider>(); |
| 78 | + |
| 79 | + // Register IServerSentEventsNoReconnectClientsIdsStore backed by memory store. |
| 80 | + services.AddInMemoryServerSentEventsNoReconnectClientsIdsStore(); |
| 81 | + |
| 82 | + ... |
| 83 | + } |
| 84 | + |
| 85 | + ... |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +## Disconnecting a Client |
| 90 | + |
| 91 | +Disconnecting a client is as simple as calling `Disconnect()` on a [`IServerSentEventsClient`](../api/Lib.AspNetCore.ServerSentEvents.IServerSentEventsClient.html). |
0 commit comments