SignalR websocket on Owin self host - websocket

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.

Related

API Server as SignalR client

I've got an ASP.NET MVC Core application which is served from a web server. The web server has a SignalR Hub and gets its data from a dedicated API server. Is it possible to register the web clients AND the API server as SignalR clients, so that the API server can push data directly to the web clients?
Yes. From the same host, inject a IHubContext<YourHub> into your controller classes and from there you can send messages to any connected clients, see more here: https://learn.microsoft.com/en-us/aspnet/core/signalr/hubcontext.
From a different host, use the SignalR client, see here: https://learn.microsoft.com/en-us/aspnet/core/signalr/dotnet-client.

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.

Xamarin messaging by Websockets SignalR

SignalR for Xamarin doesn't have way to work through Websockets.
I have a web service with messaging by SygnalR by websockets.
Can i receive message in Xamarin without implementing SignalR to Xamarin?
Is it important to have SignalR on Xamarin client side?
If you have implemented a SignalR hub in your sever, you can use SignalR Client nuget in Xamarin. The transport will be SSE (Server Sent Events) by default, but it works pretty well.
Implementing a websocket in the client just to connect to a SignalR server makes no sense at all, unless you really need to use WebSockets instead of SSE.
SignalR uses transports to connect to the server. The portable version of SignalR client does not support the webSockets transport since there is no portable version of WebSocket client available. This is fine since there are two more transports - longPolling and serverSentEvents that can be used to talk to the server.
You can't connect to the SignalR 2.x server with bare webSockets. There is a protocol that needs to be followed and if a client does not follow this protocol its requests will be rejected.
If you absolutely need to use websockets you can implement your own websockets transport by implementing the IClientTransport interface and pass it to the Start method. This is how the webSockets transport is supported on UWP. Here is all the code I needed to write.

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