What is the preferred method for using raw websockets in an ASP.NET Web API application?
We'd like to use binary WebSockets on a couple of our interfaces of our ASP.NET Web API application. I'm having a difficult time determining how this should be done as there seems to be several conflicting and/or out-dated implementations online for .NET.
There are examples which appear to be ASP.NET like this one, but I think there must be a means to use websockets within the Web API framework. As I know you can use Signalr within WebAPI.
I thought using Microsoft.AspNet.SignalR.WebSockets.WebSocketHandler would work, but I'm not sure how to link the WebSocketHandler to the Controller...
class MyServiceController : ApiController
{
[HttpGet]
public HttpResponseMessage SwitchProtocols (string param)
{
HttpContext currentContext = HttpContext.Current;
if (currentContext.IsWebSocketRequest ||
currentContext.IsWebSocketRequestUpgrading)
{
// several out-dated(?) examples would
// use 'new MySocketHandler' for ???
var unknown = new ????
currentContext.AcceptWebSocketRequest(unknown);
return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
}
}
}
class MySocketHandler : WebSocketHandler
{
public MySocketHandler(): base(2048){}
...
}
Unfortunately, AcceptWebSocketRequest no longer accepts a WebSocketHandler, instead its new signature is...
public void AcceptWebSocketRequest(Func<AspNetWebSocketContext, Task> userFunc)
Does anyone have a link or a quick sample implementing raw websockets in ASP.NET Web API application that is up-to-date?
I found this example:
Sample code (reproduced from the post):
UPDATE: After a bit more research by myself and a coworker, we came to the conclusion that the WebSocketHandler class does not appear to be intended to be used outside of the internal processes of SignalR. As there is no obvious means to leverage WebSocketHandler isolated from SignalR. This is unfortunate as I find its interfaces slightly more high-level than the System.Web/System.Net interfaces. Moreover, the method described below makes use of HttpContext which I believe should be avoided.
As such we plan to take an approach similar to the one shown by Mrchief, but with a bit more Web API flavor. Like this...(NOTE: our socket is write-only, but I discovered you MUST perform read operations of you want WebSocket.State to get updated properly.
NOTE: Obviously error checking and proper usage of a CancellationToken is left as an exercise for the reader.
What about using SignalR 2?
Sharing my code based on Tony's answer with cleaner task handling. This code sends out current UTC time approximately every second:
This is an older question, but I would like to add another answer to this.
It turns out, you CAN use it, and I have no clue why they made it so "hidden". Would be nice if someone could explain to me what's wrong with this class, or if what I'm doing here is somehow "forbidden" or "bad design".
If we look in the
Microsoft.Web.WebSockets.WebSocketHandler
, we find this public method:This method is hidden from intellisense, but it's there, and can be called without compilation errors.
We can use this method to get the task that we need to return in the
AcceptWebSocketRequest
method. Check this out:And then in my API controller:
This works completely fine. OnMessage gets triggered, and echoes back to my JavaScript instantiated WebSocket...