dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.49k stars 10.04k forks source link

ASP.NET Core SignalR - SkipNegotiation by default and use Negotiation if WebSocket connection fails. #38300

Open manishgargd opened 3 years ago

manishgargd commented 3 years ago

We are using ASP.NET Core SingalR for real time communication in our application. 90% of our web clients use WebSocket transport. By default, we don't SkipNegotiation. If a client cannot connect using WebSocket then it can fall back to other protocols for which Negotiate request is required. Even for the 90% percent of the clients using WebSocket transport, two requests, negotiate, connect are required to establish a WebSocket connection. We can improve the experience of these clients by establishing the connection in one request by skipping negotiate request.

It will be nice if the libraries can provide the feature where by default they SkipNegotiation and use WebSocket transport. If the connection is established, then we are good. If the connection fails, then library can try to create new connection without skipping Negotiation.

BrennanConroy commented 3 years ago

We will not default to enabling SkipNegotiation as that would add an extra unneeded WebSocket request in scenarios such as Azure SignalR Service.

Changing the behavior of SkipNegotiation to allow fallback if WebSockets fails is an interesting idea.

Currently we require you to explicitly specify WebSockets on the client side when using SkipNegotiation, if we changed it so you could choose not to specify the transport then we could try WebSockets without negotiation and fallback to negotiating if it fails.

This would change the meaning of SkipNegotiation to "TrySkipNegotiation" which might be ok? The only reason I can find in the original design for needing to specify WebSockets is a comment about users might file an issue if they see a negotiate with the setting set https://github.com/aspnet/SignalR/pull/2070#discussion_r182502822. Which isn't a huge issue, especially if we put doc comments on the setting and have a log if we fallback with the setting set.

Fortunately, if we did this change it wouldn't break any existing apps because they are all required to specify the WebSocket transport already. And the behavior of not trying other transports if you specify a specific one won't change if we modify the behavior as proposed.

We'll need to think about this a little to see if there are any other downsides.

alteut commented 2 years ago

Also, am I correct in thinking, that, in the meantime, we can implement this logic client-side?

Aloento commented 2 years ago

TrySkipNegotiation is better: First, try WebSocket, then, fallback to another protocol or do the negotiation. This will greatly improve SignalR's connection establishment speed.

BrennanConroy commented 2 years ago

Didn't get to this in .NET 7, but definitely still interested.

ghost commented 2 years ago

Thanks for contacting us.

We're moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.