Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
打开Web套接字取决于当前路径C#asp网络核心_C#_Asp.net_Sockets_Websocket_Asp.net Core - Fatal编程技术网

打开Web套接字取决于当前路径C#asp网络核心

打开Web套接字取决于当前路径C#asp网络核心,c#,asp.net,sockets,websocket,asp.net-core,C#,Asp.net,Sockets,Websocket,Asp.net Core,是否可以打开web套接字并连接到最终用户,但只能通过特定的路由 假设我有一个web API,它具有以下功能: 关于路线的文章部分:/articles 在线聊天模块:/chat 目前,我有一个web套接字中间件,它在最终用户使用的根目录上独立处理所有ws-request 因此,从理论上讲,只要我编写代码,就可以在应用程序前端层的任何位置建立web套接字连接 我不想要它,那么我怎样才能避免这些情况呢 以下是我当前的解决方案: using System; using System.IO; usin

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

假设我有一个web API,它具有以下功能:

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

  • 在线聊天模块:/chat

目前,我有一个web套接字中间件,它在最终用户使用的根目录上独立处理所有ws-request

因此,从理论上讲,只要我编写代码,就可以在应用程序前端层的任何位置建立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);
            }
        }
    }
}
使用系统;
使用System.IO;
使用System.Net.WebSockets;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Http;
名称空间chat.Framework
{
公共类WebSocketMiddleware
{
private readonly RequestDelegate\u next;
私人网站商(WebSocketHandler);;
公共WebSocketMiddleware(RequestDelegate下一步,WebSocketHandler WebSocketHandler)
{
_下一个=下一个;
_webSocketHandler=webSocketHandler;
}
公共异步任务调用(HttpContext上下文)
{
如果(!context.WebSockets.IsWebSocketRequest)
{
wait_next.Invoke(上下文);
返回;
}
var socket=await context.WebSockets.AcceptWebSocketAsync();
等待webSocketHandler.未连接(插座);
等待接收(套接字,异步(结果,缓冲区)=>
{
if(result.MessageType==WebSocketMessageType.Text)
{
wait_webSocketHandler.Recive(套接字、结果、缓冲区);
返回;
}
else if(result.MessageType==WebSocketMessageType.Close)
{
等待webSocketHandler.断开连接(插座);
控制台。写线(“断开”);
返回;
}
});
}
专用异步任务Recive(WebSocket套接字、操作句柄)
{
var buffer=newarraysegment(新字节[1024*4]);
WebSocketReceiveResult结果=空;
var ms=新内存流();
while(socket.State==WebSocketState.Open)
{
做
{
结果=wait socket.ReceiveAsync(缓冲区,CancellationToken.None);
}而(!result.EndOfMessage);
var newBuffer=新字节[result.Count];
复制(buffer.Array、newBuffer、result.Count);
句柄(结果,newBuffer);
控制台写入线(新缓冲长度);
}
}
}
}

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

如果我想从头开始创建聊天服务,我可能会使用SignalR,也许我将来会使用SignalR,因为这个库的当前版本不够稳定,下一个原因是我现在不需要一个完整的库。