dotnet / dotnet/aspnetcore

[Epic] SignalR Transport Updates

Open
#21,104 7 comments 1 reaction 0 assignees View on GitHub
affected-very-few area-signalr enhancement Epic severity-minor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

The idea here is to build a new transport based on HTTP streaming. The idea is for the client to establish **two** long-running HTTP requests. Termination of either request by either party tears down the whole connection (and terminates the other request). This transport is designed for HTTP/2 environments, and the transport would likely be designed to function only when the requests are actually using HTTP/2.

* One request serves as the "upstream" connection. The client sends the request headers (including auth) and then streams data to the server. The server **does not write any response** to this request until the connection terminates.

* The other request serves as the "downstream" connection. The client sends request headers and an empty body. The server sends a long-running response back and writes data to it as data becomes available. The server concludes the response when the connection is terminated.

**Why two requests?** We could have a single request with both the client and server streaming request/response data. This is permitted in the HTTP protocol. However, support for this in all platforms (Browser, .NET, Node, Java, etc.) is limited and inconsistent. Doing this two-stream model **doesn't** stop us from doing a bi-directional transport in the future.

With this transport, we can also consider deprecating Server-Sent Events. The SSE transport provides a middle-ground between Long Polling and WebSockets and has served us well but it has limitations:

* IE still doesn't support it, so it's usefulness as a "downlevel" transport is limited. The set of browsers that support WebSockets is a superset of the set of browsers that support SSE
* It can be impacted by proxies, though not as badly as WebSockets. We've encountered proxies that buffer responses which delays messages and can break connections (if timeouts elapse)
* It is limited to the JSON protocol. SSE is an inherently text-based protocol. It is sensitive to line-breaks, making it difficult to encode binary messages. While Base64 encoding is an option, we haven't use that and simply avoid using the SSE transport for MessagePack.

----

Work Items (see note below)
* [ ] https://github.com/dotnet/aspnetcore/issues/21105 Update the [Transport Protocols](https://github.com/dotnet/aspnetcore/blob/master/src/SignalR/docs/specs/TransportProtocols.md) spec to include the new HTTP Streaming transport
* [ ] Implement the HTTP Streaming transport in the .NET Server and Client
* [ ] Implement the HTTP Streaming transport in the JavaScript Client
* [ ] Update documentation on [SignalR Client Features](https://docs.microsoft.com/en-us/aspnet/core/signalr/client-features?view=aspnetcore-3.1) for 5.0
* [ ] ~https://github.com/dotnet/aspnetcore/issues/20462 Remove ServerSentEvents transport~

Note: This is something that's fairly low on our priority list for now and may not make 5.0, so we've only created issues to track the initial work (rather than spamming the tracker with a bunch of small issues). As we move forward, we'll create work items to track the rest of the work.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.