SignalR don't use websockets on IIS Express 10 - websocket

I have .NET Core 2.2 + ASP.NET Core 2.2 with SignalR inside. In my development environment I have Win7 with IIS Express 10.
Unfortunately, SignalR don't use WebSockets and unfortuantely I didn't found a way to force it to do so.
On the server side, SignalR is configured like this:
app.UseSignalR(
routeBuilder => routeBuilder
.MapHub<ClientsHub>(
"/hubs/clients",
options => options.Transports = HttpTransportType.WebSockets)
);
On the client side configuration is:
this._connection = new signalR.HubConnectionBuilder()
.withUrl(this.api.getHubUrl(url), {
transport: HttpTransportType.WebSockets
})
.build();
Negotiate request from the client side of SignalR results with this answer:
{"connectionId":"1SyteS9TsDE5Q8LBRb2-VA","availableTransports":[]}
As a result, client side of SignalR writes this message to the console:
Error: Failed to start the connection: Error: Unable to initialize any of the available transports.
This obviously means that websockets are not used and SignalR can't initialize websockets.
I've found using Google that IIS Express has websockets disabled by default and I have to enable them first. I've found some setting in IISExpress/config folder in file applicationhost.config and set it to Allow (it was Deny by default):
<section name="webSocket" overrideModeDefault="Allow" />
But nothing changes.
If to disable negotiation, SignalR client tries to use WebSockets directly using url like this:
wss://localhost:44360/hubs/clients
But this request results with error code 400:
Error during WebSocket handshake: Unexpected response code: 400
Is there any possibility to force SignalR over IIS 10 to use WebSockets?
Or to force IIS 10 to allow SignalR to use WebSockets?

I am not having an answer to your question but the reasons.
Window 7 doesn't support web sockets for IIS Express. The SO answer here and here justify it.
However, if you use Kestrel web server to run your project, it will definitely use Web sockets on Window 7. I have tested the same in a project built on .NET Core 3.1 with VS 2019.

Related

Blazor Server: Protect information in transit with HTTPS: Are WebSockets not secure enough?

Blazor Server development is great! One of my concerns is with the security of data being sent through SignalR/WebSockets.
From my understanding the communication between client and server is:
Action is taken by user e.g. clicks button
Javascript innovates the WebSocket communication with my server
Server responds with data that I've returned
Javascript changes the page (DOM)
From Chrome developer tools I can see this happening on the websocket i.e. wss://localhost/_blazor?id=XXXXXXXXXXXXXX. As the websocket is wss:// I thought communication was secure and ensured integrity and confidentiality e.g. man-in-the-middle attacks etc
So why has Microsoft advised to "Always user HTTPS" in their Blazor Server Threat Migration documentation?
Protect information in transit with HTTPS
Blazor Server uses SignalR for communication between the client and
the server. Blazor Server normally uses the transport that SignalR
negotiates, which is typically WebSockets.
Blazor Server doesn't ensure the integrity and confidentiality of the
data sent between the server and the client. Always use HTTPS.
https://learn.microsoft.com/en-us/aspnet/core/blazor/security/server/threat-mitigation?view=aspnetcore-6.0#protect-information-in-transit-with-https
Thank you to Brennan for answering my question in the comments.
So why has Microsoft advised to "Always user HTTPS" in their Blazor Server Threat Migration documentation?
The warning is just general text. The two statements on the documentation are independent of each other.
The below explains the mechanism Blazor Server typically uses for communication between client and server i.e. WebSockets
Protect information in transit with HTTPS
Blazor Server uses SignalR for communication between the client and the server. Blazor Server normally uses the transport that SignalR negotiates, which is typically WebSockets.
The below states you should always use a secure protocol when communicating between client and server i.e. HTTPS
Blazor Server doesn't ensure the integrity and confidentiality of the data sent between the server and the client. Always use HTTPS.
I assumed Microsoft was referring to using standard API (HTTP/2) endpoints to ensure integrity and confidentiality. As Brennan pointed out - WebSockets is an extension of HTTP/1.1, and thus can use HTTPS.
Hopefully, this helps people in the future.

Enable signalr to accept WS connections

I have created a dotnet core signalr project, and I want to allow other users to connect on the signalr web socket like I can do it when I connect on:
wss://echo.websocket.org
Currently, signalr generates ID when creating the negotiation, and when switching on wss it uses that id, but it is causing a problem when using external connections.
So, is it possible to tell SignalR not to generate the id when creating the websocket server, and also to accept external ws connections ?
try to use dotnet core websockets
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-2.2

SignalR websocket on Owin self host

I was trying SignalR on Owin Self host. Everything works file but SignalR falls back to server send event instead of using WebSockets.
I know IIS 7.5 (Windows 7) does not support websockets but since this is Owin Self host, I was under impression that it is not dependent on IIS and HTTP.sys and websockets should work.
Even Scott Hanselman commented on below link that with OWIN we can do WebSockets anywhere:
https://aspnet.uservoice.com/forums/41199-general-asp-net/suggestions/3090811-websockets-support-in-asp-net-4-5-should-not-be-li
Does anyone how how to do true websockets with SignalR (or any other approach) and Owin running on Windows 7?
The OWIN WebSocket spec doesn't have any OS dependencies, but it does rely on having a server that implements it. Try Nowin: https://github.com/Bobris/Nowin
HttpListener used in Katana self-host still depends on Http.Sys and requires Win8+ for WebSocket support.

SignalR - Always downgraded to server sent events in Chrome/Firefox

I have an API application and a web application (for simplicity on the same server -- I'll do the CORS stuff later).
Windows Server 2012 with IIS 8.5
Websockets installed through "Programs and features"
Firewall turned off
The api is using owin + signalr and has the proper initialization (trimmed it down to find the error):
public void Configuration(IAppBuilder app)
{
GlobalHost.Configuration.TransportConnectTimeout = TimeSpan.FromSeconds(5);
app.MapSignalR();
app.UseWebApi(Startup.CreateConfiguration());
}
private static HttpConfiguration CreateConfiguration()
{
HttpConfiguration configuration = new HttpConfiguration();
configuration.MapHttpAttributeRoutes();
return configuration;
}
Everything seems to work perfectly except connection to the actual websockets. Every time the client tries to establish a connection, there is a timeout and it fails over to SSE (or forever frame/long polling in IE). I increased the timeout to 25 seconds and the same symptoms are occurring.
On the client, I consistently get this error with logging turned on:
SignalR: Connecting to websocket endpoint 'ws://[myurl]'.
SignalR: Websocket opened.
SignalR: **webSockets timed out when trying to connect.**
SignalR: Closing the Websocket.
SignalR: Attempting to connect to SSE endpoint 'http://[myurl]'.
SignalR: EventSource connected.
SignalR: serverSentEvents transport selected. Initiating start request.
SignalR: The start request succeeded. Transitioning to the connected state.
I have tried following the guides provided by the signalR team and I cannot see what I am missing.
Thanks for any help!
UPDATE:
I downloaded a sample and ran it as-is on the server.
Same situation, so this is likely a server configuration setting that I missed along the way. I still have not found what I missed.
You need to enable WebSockets for the website in Server Manager.
http://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-websocket-protocol-support
Try establishing a SignalR connection from your Windows Server machine itself. This might have something to do with the network. Perhaps there's a proxy or something in between the client and server that doesn't properly support WebSockets.
If you are inside of a network with a "corporate" firewall, it can screw up the websockets handshake.
But, you can prevent this interference if you access your server over SSL. I've seen this first hand be the cause and solution multiple times for websockets problems in corporate environments.
It may be something with your IIS settings. I saw these on http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/supported-platforms
-IIS must be running in integrated mode; classic mode is not supported. Message delays of up to 30 seconds may be experienced if IIS is run in classic mode using the Server-Sent Events transport.
-The hosting application must be running in full trust mode.
Also, it mentioned something about .NET 4.5 being the target framework. Hope this helped.

Websockets in .NET 4.5

I want to develop a web application in which client calls a service on server to do some action which involves some processing. Server will do all the necessary processing and when the updated data is ready it will push that data to client. Currently I am considering two approaches: -
1. Using ASP.NET WEB API with SignalR
2. Using WebSockets with WCF in .NET 4.5.
My server will be on Windows Server 2012 but majority of my client will be IE 9 which I think do not support WebSockets.
As written in the SignalR documentation that it automatically falls to Long Polling if WebSockets support is not present without changing the application code. Whether this is also supported by WebSockets in .NET 4.5 or I have to do it manually. Means whether I have to implement both the Pull method and push method on the server.
Please guide me, which approach I will have follow.
In later use case I want to build this web application using PhoneGAP to create mobile app for iOS, Android & Windows Phone.
WebSockets does not fall back to longpolling (that doesn't really make sense). SignalR is a higher level abstraction over http transports and that's why it does the fallback and other things (like provide a nice programming model over a connection).
If you choose to use websockets on ASP.NET (not sure about WCF) you'll be programming against raw sockets (this means reading/writing array segments etc) and doing a good job at that is hard. SignalR does this for you and will fallback to several other transports (forever frame, server sent events, longpolling) if websockets isn't available on client or server.
Regarding clients, if you choose to use SignalR you'll need to use a SignalR client. We only have support for javascript and .NET (silverlight, windows phone 8, winrt, .NET 4 and .NET 4.5). Some people have written clients for other platforms including iOS and Android but we don't maintain them so I can't speak to how up to date they are.
I'd recommend you use SignalR so you can focus on your application logic instead of messing with the low level programming model of websockets.
You could start with the ASP.NET Tutorial http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr
After this tutorials you know all the basic thing you need to know about SignalR
I can confirm that the fallback works automatically. If websockets transport can't be used, ServersentEvents transport would be used.. and so on.. the last transport protocol is longpolling.
Our SignalR server is a .NET 4.5 framework app, hosted in an ASP.NET MVC App using 4.5 dlls on a windows 2012 server. The application pool is ASP.NET 4.0.
A .NET 4.5 client on a Windows 8 or a windows 2012 server seems to use websockets.
The same .NET client on a Windows 7 machine (even with framework 4.5 installed) falls back to serversent events transport automatically.
With Signalr javascript clients on a browser, a similar thing happens:
Chrome/Safari/other browsers that support websockets seem to use websockets.
IE/other browsers that don't support websockets, but are relatively late versions seem to use serversentevents.
From experience, serversentevents is not very bad, therefore don't be put off if websockets isn't being used and certainly don't use that as the sole factor against using signalR as the benefits are many.
Hope this helps.

Resources