将 WebSocket 与 ASP.NET Web API 结合使用

2024-01-01

在 ASP.NET Web API 应用程序中使用原始 Websocket 的首选方法是什么?

我们想用binaryASP.NET Web API 应用程序的几个接口上的 WebSocket。我很难确定应该如何完成此操作,因为 .NET 的在线实现似乎有几个相互冲突和/或过时的实现。

有一些看起来像 ASP.NET 的例子one http://www.codeguru.com/csharp/csharp/programming-html5-web-sockets-in-asp.net-4.5.htm, but I think必须有一种在 Web API 框架内使用 websockets 的方法。据我所知,您可以在 WebAPI 中使用 Signalr。

I thought使用 Microsoft.AspNet.SignalR.WebSockets.WebSocketHandler 可以工作,但我不确定如何将 WebSocketHandler 链接到控制器...

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){}

    ...
}

不幸的是,AcceptWebSocketRequest 不再接受 WebSocketHandler,而是它的新签名......

public void AcceptWebSocketRequest(Func<AspNetWebSocketContext, Task> userFunc)

有谁有在最新的 ASP.NET Web API 应用程序中实现原始 websockets 的链接或快速示例吗?


UPDATE:经过我和同事的更多研究,我们得出的结论是 WebSocketHandler 类似乎不适合在 SignalR 内部进程之外使用。因为没有明显的方法来利用与 SignalR 隔离的 WebSocketHandler。不幸的是,我发现它的接口比 System.Web/System.Net 接口稍微高级一些。此外,下面描述的方法利用了我所使用的 HttpContextbelieve应该避免。

因此,我们计划采用与 Mrchief 所示的方法类似的方法,但具有更多的 Web API 风格。像这样......(注意:我们的套接字是只写的,但我发现你MUST执行您希望 WebSocket.State 正确更新的读取操作。

class MyServiceController : ApiController
{
    public HttpResponseMessage Get (string param)
    {
        HttpContext currentContext = HttpContext.Current;
        if (currentContext.IsWebSocketRequest || 
            currentContext.IsWebSocketRequestUpgrading)
        {
            currentContext.AcceptWebSocketRequest(ProcessWebsocketSession); 
            return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
        }   
    }

    private async Task ProcessWebsocketSession(AspNetWebSocketContext context)
    {
        var ws = context.WebSocket;

        new Task(() =>
        {
            var inputSegment = new ArraySegment<byte>(new byte[1024]);

            while (true)
            {
                // MUST read if we want the state to get updated...
                var result = await ws.ReceiveAsync(inputSegment, CancellationToken.None);

                if (ws.State != WebSocketState.Open)
                {
                    break;
                }
            }
        }).Start();

        while (true)
        {
            if (ws.State != WebSocketState.Open)
            {
                break;
            }
            else
            {
                byte[] binaryData = { 0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe };
                var segment = new ArraySegment<byte>(binaryData);
                await ws.SendAsync(segment, WebSocketMessageType.Binary, 
                    true, CancellationToken.None);
            }
        }
    }
}

注意:显然,错误检查和 CancellationToken 的正确使用留给读者作为练习。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 WebSocket 与 ASP.NET Web API 结合使用 的相关文章

随机推荐