2.12Long Polling
Long polling (Long Polling) is a technique for pushing data from the server to the client. It simulates the effect of server push by keeping the HTTP connection open until new data is sent to the client, or until a timeout occurs. Long polling is an improvement over traditional polling (where the client periodically sends requests to the server to check for new data), which can reduce unnecessary requests and improve efficiency.
How long polling works:
- The client initiates a request to the server.
- If there is no new data on the server, the server does not immediately respond to the request but instead holds the request.
- Once new data is available on the server to send, or the preset timeout is reached, the server responds to the request and sends the data to the client.
- After the client finishes processing the data, it initiates a new request to the server again, repeating the above process.
Application scenarios of long polling:
- Real-time notifications: For example, in online chat applications, when a user receives a new message, the server can promptly push the message to the client through long polling.
- Online collaboration tools: Such as applications where multiple people edit a document simultaneously; long polling can be used to synchronize users' editing operations in real time.
- Game updates: In online games, long polling can be used to update game state in real time, such as player positions, scores, and other information.
- Stock market updates: Financial applications use long polling to display stock price changes in real time.
- Configuration centers: In a microservices architecture, configuration centers use long polling to ensure that each service can immediately receive the latest configuration changes. When a configuration changes, the configuration center can quickly push the update to all relevant service instances, ensuring configuration consistency and timeliness.
The following example shows how to use a long polling request:
await httpRemoteService.LongPollingAsync("https://localhost:7044/HttpRemote/LongPolling" , async (responseMessage, token) => { Console.WriteLine(await responseMessage.Content.ReadAsStringAsync(token)); await Task.CompletedTask; }, cancellationToken: cancellationToken);// Using the builder patternawait httpRemoteService.SendAsync(HttpRequestBuilder .LongPolling("https://localhost:7044/HttpRemote/LongPolling" , async (responseMessage, token) => { Console.WriteLine(await responseMessage.Content.ReadAsStringAsync(token)); await Task.CompletedTask; }), cancellationToken: cancellationToken);Long polling also supports consuming data as IAsyncEnumerable<HttpResponseMessage>, allowing you to use await foreach to iterate over each polling response:
await foreach (var responseMessage in httpRemoteService.LongPollingAsAsyncEnumerable("https://localhost:7044/HttpRemote/LongPolling", cancellationToken: cancellationToken)){ // Note: each response needs to be manually disposed after use (or use using) using (responseMessage) { Console.WriteLine(await responseMessage.Content.ReadAsStringAsync(cancellationToken)); }}// Using the builder patternawait foreach (var responseMessage in httpRemoteService.SendAsAsyncEnumerable(HttpRequestBuilder.LongPolling("https://localhost:7044/HttpRemote/LongPolling"), cancellationToken)){ using (responseMessage) { Console.WriteLine(await responseMessage.Content.ReadAsStringAsync(cancellationToken)); }}Although long polling addresses the need for real-time communication to a certain extent, it also has some disadvantages. For example, under high concurrency it may put considerable pressure on the server, and long-lived connections may affect server performance. As Web technologies evolve, more advanced technologies such as Server-Sent Events or WebSocket are gradually becoming the preferred solution for real-time bidirectional communication. However, in certain restricted environments, long polling is still a viable choice.