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

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.

Related

HttpClient timeout on Braintree call in Blazor

I'm deploying my .Net 6, Blazor Server site for the first time on shared hosting. It's all seems to work so far bar two things.
In the browser console (Chrome) I get an error:
Error 1
blazor.server.js:1 WebSocket connection to 'wss://www.mysite.co.uk/_blazor?id=qW5eCRVc_HbgSWt8iESawA' failed:
Information: (WebSockets transport) There was an error with the transport.
Error: Failed to start the transport 'WebSockets': Error: WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled.
Warning: Failed to connect via WebSockets, using the Long Polling fallback transport. This may be due to a VPN or proxy blocking the connection. To troubleshoot this, visit https://aka.ms/blazor-server-using-fallback-long-polling.
The page seems to work & I've added all the CSP entries I can find so that's the only error left.
Error 2 is when I call Braintree to capture a payment. That's the only Braintree call & it works fine locally.
Transaction.SubmitForSettlementAsync(transactionId, amount)
gets an exception : The request was canceled due to the configured HttpClient.Timeout of 60 seconds elapsing.
I have no idea why that is & assume is blocking is call. Any help would be appreciated.
For this warning:
Warning: Failed to connect via WebSockets, using the Long Polling fallback transport. This may be due to a VPN or proxy blocking the connection. To troubleshoot this, visit https://aka.ms/blazor-server-using-fallback-long-polling.
see: https://learn.microsoft.com/en-us/aspnet/core/signalr/publish-to-azure-web-app?view=aspnetcore-5.0#configure-the-app-in-azure-app-service
For apps hosted without the Azure SignalR Service, enable:
ARR Affinity to route requests from a user back to the same App Service > instance. The default setting is On.
Web Sockets to allow the Web Sockets transport to function. The default setting is Off.
In the Azure portal, navigate to the web app in App Services.
Open Configuration > General settings.
Set Web sockets to On.
Verify that ARR affinity is set to On.

SignalR don't use websockets on IIS Express 10

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.

ConnectionFailedException : Websocket connection failed

I am taking over an iOS application connecting to the server through a Web socket connection using the Kaazing Websocket (JMS edition) client side javascript library.
I am using Phonegap for my iOS application and be able to test it both on Chrome and the iOS simulator. About 30% of the time I get a connection error from the library testing on chrome and 70% for testing on the iOS simulator/device. I get an Exception being thrown in the minified js library which just say "ConnectionFailedException : Websocket connection failed" Seems like this is a browser specific issue but I cannot do anything further about it.
I can't directly take a look at the server located in the UK but asking them for debug logs. So I asked for the logs from server and these are the errors that I spotted out that might be the reason:
2014-03-05 08:09:23,670 [NioProcessor-15] DEBUG session.revalidate - No WebSocket authorization timeout has been configured, so no revalidate period can be inferred.
2014-03-05 08:09:23,670 [NioProcessor-15] INFO session.revalidate - WebSocket Session [176128] is not being re-validated because no timeout has been specified for the negotiated "x-kaazing-http-revalidate" extension.
Anybody have any idea about this x-kaazing-http-revalidate and if not, what is the proper way to debug these Websocket connection?
Full disclaimer, I work at Kaazing.
x-kaazing-http-revalidate is a Kaazing HTTP extension, negotiated while establishing WebSocket connection. This is done by setting the authorization-timeout in the gateway-config.xml file (the configuration file we ship has an example). The intention of this extension is to periodically revalidate the user's authorization, because entitlements could change over the duration of a long-running connection.
ConnectionFailedException : WebSocket connection failed can occur, if some intermediaries/proxies associated with the service providers inject an unknown or a suspicious header/s in the WebSocket connection request. If the injected header is unknown/suspicious, then Kaazing gateway will not complete the connection, to avoid intruders from eavesdropping. Using a secure TLS/SSL connection should resolve the intermediary related issues.
To debug and to setup a secure javascript client please follow instructions from the documentation. You can also use WebSocket-debug.js instead of WebSocket.js with script tags in the jms-javascript.html file for more logging. There is also a Walkthrough: Deploy a JavaScript JMS App as a Hybrid iOS App.

SignalR Hub's Groups dont work with long polling

I have a Web App(.NET 4.0 ASP.NET MVC3) which uses SignalR(1.0.0 alpha 2) with Hubs and Persistent Connections.
With the Hubs I use groups to send push notifications to some clients.
The problem is that when the server is accessed remotely it defaults to long pooling and only the persistent connections work. With hubs the event happens on the server but my callback is not called at the client. It works locally, though it uses SSE.
What I found is that the combination of Grouping the clients and the long pooling transport is causing the problem. I will try to debug SignalR as long as I get VS2012.
To prove this I just got this chat example modified so a hard-coded group was used and long pooling was forced - it does not work, neither on my machine (IISExpress) nor on a server (IIS 7.5). The chat works as long as you use a different transport OR do
context.Clients.All.addMessage(message);
instead of
context.Clients.Group(groupName).addMessage(message);
Here is a sample project.
Is that a bug in SignalR or I'm missing something?
Any ideas why on my deployment server SignalR would fall back to long polling on port 80 but use SSE if my site is configured on a different port?
You need to enable Auto-Rejoining groups.
Stick this in your startup code:
GlobalHost.HubPipeline.EnableAutoRejoiningGroups();

Continuous websocket traffic with SignalR

I've been using SignalR successfully for some time using serverSentEvents transport. I've just installed my application on Windows Server 2012 RC and now when I connect SignalR is using websockets (as you'd expect).
It appears to work OK except there is a continuous stream of websocket traffic between server and browser - about once a second it's sending about 90 bytes.
From the debugger window in Chrome, it looks like it's sending a connection upgrade request each time.
I am successfully receiving messages sent by the server, but I seem to be worse off than when using long polling.
The browser is Chrome version 19.0.1084.52.
Any idea why this is happening?
This was down to my own stupidity - but I thought I'd answer in case anyone else has the same problem.
I had built the solution SignalR.Hosting.AspNet instead of SignalR.Hosting.AspNet45
So the method AcceptWebSocketRequest was throwing a NotSupportedException; because the client websocket upgrade failed, it just tried again about a second later.
I guess the client could show an error or something in this case to aid debugging.

Resources