2017-08-29 49 views
0

是否可以打開Web套接字並連接到最終用戶,但只能通過特定的路由?Open Web Socket取決於當前路由C#asp net core

讓我們假設我有一個Web API,它具有以下功能:在路線

  • 文章部分:/條路線上

  • 聊天模塊:/聊天

現在我有一個Web套接字中間件,它可以在最終用戶使用的根上獨立處理所有的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); 
      } 
     } 
    } 
} 
+0

如果我想從頭創建一個聊天服務,而不是摸索Web套接字,我可能會使用SignalR。 – Maritim

+0

可能我將來會使用SignalR,因爲這個庫的當前版本不夠穩定,下一個原因是我現在不需要整個庫。 – bielu000

回答

1

ASP.NET核心中間件在每一個請求上運行,所以如果你想要做的路由邏輯,你需要實現它中間件裏面。對於你的兩條路線,這應該非常簡單,只需在接受WebSocket之前在Invoke方法中檢查context.Request.Path以確定要處理的連接類型。