【问题标题】:.NET Core Middleware is not invoked未调用 .NET Core 中间件
【发布时间】:2018-06-30 07:04:55
【问题描述】:

您好,我有以下问题:

我正在尝试通过websockets 将对象从Console Application 发送到ASP NET Core Server

Console 应用程序上,我使用NewtonSoft Json 序列化一个对象,然后通过Socket 将其发送到.NET Core 服务器。

在服务器上,我创建了一个小型中间件。Invoke 方法只是没有被调用。

我保持两个 Visual Studio 实例处于打开状态,服务器端没有任何反应,直到我关闭客户端连接,服务器端弹出此错误 - 终端:

1 服务器

1.1 程序

    class Program
        {
            static void Main(string[] args)
            {
                BuildWebHost(args).Run();
            }
            public static IWebHost BuildWebHost(string[] args)=>

                WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseKestrel()
                .UseSockets()
                .UseUrls("http://localhost:8200")

                .Build();
        }

1.2 启动类

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddSingleton<WebSocketService>(x=>new WebSocketService());

        }
        public void Configure(IApplicationBuilder builder)
        {

            builder.UseWebSockets();
            builder.UseMiddleware<SocketMiddleware>();


        }
    }

1.3 中间件

class SocketMiddleware
    {
        WebSocketService handler;
        public SocketMiddleware(WebSocketService _handler,RequestDelegate del)
        {
            this.handler = _handler;
            this.next = del;
        }

        RequestDelegate next;

        public async Task Invoke(HttpContext context)
        {


            if (!context.WebSockets.IsWebSocketRequest)
            {
                await  this.next(context);
                return;
            }
            await this.handler.AddClientAsync(context.WebSockets);

        }
    }

注意:我不会发布中间件使用的服务的代码,因为它与这种情况无关。invoke 不会被调用。

2 客户

客户端只是序列化一个 POCO 类 Player 并通过套接字发送它。然后它等待服务器响应 Player 列表。

static async Task Main(string[] args)
        {
            Player updatePlayer = new Player(100);
            List<Player> players;
            Memory<byte> buffer = new byte[2000];
            ReadOnlyMemory<byte> toSend;
            ReadOnlyMemory<byte> actualReceived;
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8200);
            Random rand = new Random();

            await socket.ConnectAsync(iPEndPoint);
            using(NetworkStream stream =new NetworkStream(socket))
            {
                while (true)
                {
                    updatePlayer.Lat = rand.Next(10, 100);
                    updatePlayer.Lng = rand.Next(10, 100);

                    string data=JsonConvert.SerializeObject(updatePlayer);
                    toSend = Encoding.UTF8.GetBytes(data);
                    await stream.WriteAsync(toSend);

                    int received=await stream.ReadAsync(buffer);
                    actualReceived = buffer.Slice(0, received);
                    string msg = Encoding.UTF8.GetString(actualReceived.ToArray());
                    players = JsonConvert.DeserializeObject<List<Player>>(msg);
                    if (Console.ReadKey().Key == ConsoleKey.Escape)
                    {
                        break;
                    }

                }
            }


        }

P.S 服务器使用websockets 并且在客户端我使用socket 类可能是一个问题吗?我认为只要目标地址和端口都可以..它只是字节。

【问题讨论】:

  • “我不会发布中间件使用的服务的代码,因为它与这种情况无关。” – 不确定我是否同意。您的中间件请求被中断了,因此您与 Web 套接字请求的交互方式确实很重要。话虽如此,您确定您的客户端工作吗?您是否尝试改用浏览器?另外,日志中还有其他内容吗?
  • 我已经尝试过 chrome 提供的 websocket 客户端,它可以工作。我也尝试过 angular 2 js 客户端,它仍然有效。Invoke 方法被调用。为什么@ 987654341@不会调用它?我想可能是我发送了原始Tcp 而.NET 框架需要HTTP GET
  • 你检查WebSocket specification了吗? WebSockets 不仅仅是裸 TCP 套接字,它们是 HTTP 连接的升级,所以你不能仅仅打开一个这样的套接字并期望能够发送数据。
  • 是的,我知道首先您发送一个 HTTP 请求,该请求将升级到 websocket(原始 tcp)。但是您如何包装您的请求来做到这一点?我的意思是带有一个原始套接字应该如何在 C# 中处理?
  • 如果你想使用原始 TCP 套接字,你必须自己实现协议。否则,您可能应该使用 WebSocket 客户端库。

标签: asp.net-core websocket .net-core middleware


【解决方案1】:

Server.cs 中,Invoke 方法 有一个WebSocketManager 类型的参数。

我们可以接受WebSocket 连接但不是原始的 Socket
因此,在 Client.cs 中,我将原始的 Socket 替换为 WebSocket 实现。

【讨论】:

    猜你喜欢
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-28
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    相关资源
    最近更新 更多