Open Web Socket依赖于当前路由C#asp net core

时间:2017-08-29 19:16:59

标签: c# asp.net sockets websocket asp.net-core

是否可以打开Web套接字并连接到最终用户,但只能通过特定路由?

假设我有一个具有以下功能的Web API:

  • 关于路线的文章部分:/ articles

  • 路线上的
  • 聊天模块:/ chat

此时我有一个Web套接字中间件,可以在root上独立处理所有ws请求,最终用户使用它。

因此,理论上,如果我只编写能够执行此操作的代码,则可以在应用程序的前端的任何位置建立Web套接字连接。

我不想要它,所以我该如何预防这些情况呢?

以下是我目前的解决方案:

using System;
using System.IO;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace chat.Framework
{
    public class WebSocketMiddleware
    {
        private readonly RequestDelegate _next;
        private WebSocketHandler _webSocketHandler;

        public WebSocketMiddleware(RequestDelegate next, WebSocketHandler webSocketHandler)
        {
            _next = next;
            _webSocketHandler = webSocketHandler;
        }

        public async Task Invoke(HttpContext context)
        {
            if (!context.WebSockets.IsWebSocketRequest) 
            {
                await _next.Invoke(context);

                return;
            }

            var socket = await context.WebSockets.AcceptWebSocketAsync();
            await _webSocketHandler.OnConnected(socket);

            await Recive(socket, async(result, buffer) => 
            {
                if(result.MessageType == WebSocketMessageType.Text)
                {
                    await _webSocketHandler.Recive(socket, result, buffer);

                    return;
                }
                else if (result.MessageType == WebSocketMessageType.Close)
                {
                    await _webSocketHandler.OnDisconnected(socket);
                    Console.WriteLine("Disconnect");
                    return;
                }
            });
        }

        private async Task Recive(WebSocket socket, Action<WebSocketReceiveResult, byte[]> handle)
        {
            var buffer = new ArraySegment<byte>(new Byte[1024 * 4]);
            WebSocketReceiveResult result = null;        

            var ms = new MemoryStream();

            while(socket.State == WebSocketState.Open)
            {
                do
                {
                    result = await socket.ReceiveAsync(buffer, CancellationToken.None);

                } while (!result.EndOfMessage);

                 var newBuffer = new byte[result.Count];
                Array.Copy(buffer.Array, newBuffer, result.Count);

                handle(result, newBuffer);
                Console.WriteLine(newBuffer.Length);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

ASP.NET核心中间件在每个请求上运行,因此如果您想要执行路由逻辑,则需要在中间件中实现它。对于您的两个路由,这应该非常简单,只需在接受WebSocket之前检查context.Request.Path方法中的Invoke,以确定要处理哪种连接。