Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kestrel support for WebSockets over HTTP/2 #7801

Closed
johncrim opened this issue Feb 21, 2019 · 15 comments · Fixed by #41558
Closed

Kestrel support for WebSockets over HTTP/2 #7801

johncrim opened this issue Feb 21, 2019 · 15 comments · Fixed by #41558
Assignees
Labels
affected-very-few This issue impacts very few customers api-approved API was approved in API review, it can be implemented area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions enhancement This issue represents an ask for new feature or an enhancement to an existing one severity-nice-to-have This label is used by an internal tool
Milestone

Comments

@johncrim
Copy link

Is your feature request related to a problem? Please describe.

I would like to be able to use WebSockets over HTTP2 - my understanding is that this is not currently supported, though I have not found any documentation about it or API support for it. My research shows that WebSockets and HTTP2 are independent within Kestrel and ASP.NET Core.

Describe the solution you'd like

If HttpProtocols.Http2 is enabled, and the WebSocketsMiddleware is enabled, support WebSockets over HTTP2 connections, per RFC 8441.

@analogrelay
Copy link
Contributor

analogrelay commented Apr 10, 2019

What client are you looking to use? I'm not aware of any browsers that support WebSockets over HTTP/2, nor does the .NET client (or any other language client that I'm aware of looks like node has this on the server at least). Can you provide more information on why WebSockets over HTTP/2 is important to your scenario?

@analogrelay analogrelay added this to the Backlog milestone Apr 12, 2019
@analogrelay analogrelay added the enhancement This issue represents an ask for new feature or an enhancement to an existing one label Apr 12, 2019
@johncrim
Copy link
Author

Certainly: We want to use HTTP/2 whenever supported, for better user-perceived perf, and better mobile experience. Primary clients are Chrome, Chrome/Android, Safari, Safari/iOS. We also use WebSockets in our app, and want to be able to establish a WebSocket connection from an HTTP/2 connection.

@analogrelay
Copy link
Contributor

Good to know. Right now Chrome is the only browser that supports this. Firefox is apparently developing support and with Edge moving to the Chromium engine, it will likely inherit Chrome's support. Safari has made no public signals either way.

What scalability benefit do you expect to get from using WebSockets over HTTP/2? In high scalability environments, it's generally recommended to run WebSocket traffic through a separate server. When doing that, the benefits of WebSockets over HTTP/2 almost entirely disappear since you only have one connection from each client anyway. There are benefits to be gained from mixed environments where WebSocket traffic is running on the same server. Plus, we don't fully understand yet what those benefits would be (I'd anticipate them to be fairly minor).

There's certainly nothing incorrect about running standard HTTP traffic over HTTP/2 and WebSockets through HTTP/1.1 (this is how most browsers/servers/applications behave today).

In order to get a better idea of how this could help (so we can prioritized accordingly) it would help to know if you are seeing scalability issues due to a high number of WebSocket connections from the same clients. That's a scenario where WebSockets over HTTP/2 has a benefit.

@MT-UE
Copy link

MT-UE commented Apr 27, 2019

Isn't a heavy tabbing user in a server side blazor app exactly that use case?

When I think further it may also be a general fitting framework/solution for any kind of TCP connection framing capabilities based on a well understood and supported standard (as far as I know http2 itself can do that also, but I'd like to go the web sockets road with my experimental projects).

And last but not least, it will allow some simple ways to do "little" scale-out (i.e. if needed 200 client connections instead of 100 default limit) by simply put the application server behind two "front end" servers (I don't know if generally CPU or connections is the bottleneck)

What about reverse proxy scenarios?

Disclaimer: some of the ideas may not survive a real project attempt - not even an experimental project attempt.

@analogrelay
Copy link
Contributor

analogrelay commented Apr 28, 2019

Isn't a heavy tabbing user in a server side blazor app exactly that use case?

Yep, this is a major reason why Blazor added support for using the Azure SignalR Service back in 0.6.0 (see https://devblogs.microsoft.com/aspnet/blazor-0-6-0-experimental-release-now-available/). When using the Azure SignalR Service, the WebSockets traffic is offloaded to a different server. When do you offload to a different server you'll always end up with a new TCP connection (even on HTTP/2, since connections are per-origin). Thus reducing the value of WebSockets over HTTP/2.

I do want to clarify that I agree this is a spec that we should look to supporting in the future. I'm just laying out our thoughts on priority. We're basically fully-booked for 3.0, so this is on the Backlog.

@johncrim
Copy link
Author

johncrim commented Apr 29, 2019

IMO how WebSockets are partitioned and used is an application concern. Our specific use-case is low-traffic websockets, and the app supports partitioning by user subscription (eg ServiceFabric stateful service). For us it makes sense to handle API requests and websocket connections on the same server, though in the event of an outage we'll fail over to another server.

Until this is supported by all browsers that we care about we'll have to support using separate HTTP 1.1 websockets in addition to H2 websockets; my first reason for posting this issue was to flag it for consideration, and secondly we'd like to use it when possible. It's not a blocker for us, but I would expect efficiency benefits from the feature.

@jkotalik jkotalik added affected-very-few This issue impacts very few customers severity-nice-to-have This label is used by an internal tool labels Nov 13, 2020 — with ASP.NET Core Issue Ranking
@davidfowl
Copy link
Member

We need to bring this back to life now that it's in chrome https://chromestatus.com/feature/6251293127475200

@Tratcher Tratcher modified the milestones: Backlog, .NET 7 Planning Oct 29, 2021
@Tratcher Tratcher self-assigned this Oct 29, 2021
@Tratcher
Copy link
Member

Clients: This is now supported in Chrome, Edge, and Firefox.
https://wpt.fyi/results/websockets/opening-handshake/002.html%3Fwpt_flags%3Dh2?label=experimental&label=master&aligned

@johncrim
Copy link
Author

While any .NET service hosting websockets should benefit from this, the YARP Reverse Proxy Library will likely benefit, saving a number of Microsoft products some money....

@adityamandaleeka adityamandaleeka changed the title Kestrel support for WebSockets over HTTP2 Kestrel support for WebSockets over HTTP/2 Jan 29, 2022
@ivanjx
Copy link

ivanjx commented Mar 22, 2022

i am using nginx as the reverse proxy. is there any guide or sample configuration for nginx that i can look into so i can apply it when this feature is ready? currently my nginx is terminating https connection and the upstream is via http 1.1. thanks

@davidfowl
Copy link
Member

Does nginx support websockets over h2?

@gstrauss
Copy link

Does nginx support websockets over h2?

No, not yet, according to: https://trac.nginx.org/nginx/ticket/1992

@Tratcher
Copy link
Member

Tratcher commented Jun 3, 2022

Api Proposal:

Also includes #42002

This feature allows the server to communicate to the middleware support for this new H2 Connect mechanism. WebTransport will likely use the same mechanism for H2 and H3.

namespace Microsoft.AspNetCore.Http.Features;

public interface IHttpConnectFeature
{
    bool IsConnectRequest { get; }
    string? Protocol { get; }
    ValueTask<Stream> AcceptAsync();
}

Risks:
It's unclear if other servers like Http.Sys will eventually support H2 WebSockets or this H2 CONNECT mechanism, and if they do, if this abstraction will match. At a guess, they'd re-map the request to look like HTTP/1.1 WebSockets and re-use the original APIs.

@Tratcher Tratcher added the api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews label Jun 3, 2022
@ghost
Copy link

ghost commented Jun 3, 2022

Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:

  • The PR contains changes to the reference-assembly that describe the API change. Or, you have included a snippet of reference-assembly-style code that illustrates the API change.
  • The PR describes the impact to users, both positive (useful new APIs) and negative (breaking changes).
  • Someone is assigned to "champion" this change in the meeting, and they understand the impact and design of the change.

@halter73
Copy link
Member

halter73 commented Jun 6, 2022

API Review notes:

  • Do we need another way to check if the request is using the "CONNECT" verb?
    • We only set this to true for "extended" CONNECT requests.
    • Let's rename to IsExtendedConnect.
  • Should we rename the interface to IHttpExtendedConnectFeature.
    • Why not? It won't be referenced much directly by apps.
  • When IsExtendedConnect is true, Protocol is not null. Let's use the attribute for that.
namespace Microsoft.AspNetCore.Http.Features;

+ public interface IHttpExtendedConnectFeature
+ {
+    [MemberNotNullWhen(true, nameof(Protocol))]
+    bool IsExtendedConnect { get; }
+    string? Protocol { get; }
+    ValueTask<Stream> AcceptAsync();
+ }

@halter73 halter73 added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews labels Jun 6, 2022
@Tratcher Tratcher modified the milestones: .NET 7 Planning, 7.0-preview6 Jun 8, 2022
@dotnet dotnet locked as resolved and limited conversation to collaborators Jul 8, 2022
@amcasey amcasey added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affected-very-few This issue impacts very few customers api-approved API was approved in API review, it can be implemented area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions enhancement This issue represents an ask for new feature or an enhancement to an existing one severity-nice-to-have This label is used by an internal tool
Projects
None yet
Development

Successfully merging a pull request may close this issue.

12 participants