首页 > 解决方案 > SignalR 核心控制台客户端未收到通知

问题描述

我环顾了一些类似的问题,并没有解决这个问题。我的 .NET 核心 Web API 项目中有一个简单的集线器。这是集线器:

 public class NotificationHub : Hub<INotificationClient>
{
  public async Task SendMessage(string user, string msg)
    {
        await Clients.All.ReceiveMessage(user, msg);
    }
    public Task SendMessageToCaller(string msg)
    {
        return Clients.Caller.ReceiveMessage(msg);
    }

    public Task SendMessageToPartner(string user, string msg)
    {
        return Clients.Client(user).ReceiveMessageToPartner(msg);
    }
}

这是界面:

 public interface INotificationClient
{
    Task ReceiveMessage(string user, string msg);
    Task ReceiveMessage(string msg);
    Task ReceiveMessageToPartner( string msg);

}

这是来自控制器的代码:

[Route("[controller]")]
[ApiController]
public class NotificationsController : ControllerBase
{
    private IHubContext<NotificationHub> _hub;

    public NotificationsController(IHubContext<NotificationHub> hub)
    {
        _hub = hub;

    }
    [HttpGet]
    public async Task<IActionResult> Get()
    {
        var msg = new NotificationData { ClientId = "12345", Notification = "Somone just connected" };
        await _hub.Clients.All.SendAsync("Notification", msg);
        return Ok(new { Message = "Request complete" });
    }
}

最后是控制台客户端代码:

 Console.WriteLine("Press a key to start listening");
        Console.ReadKey();

        Console.WriteLine("Client Listening!");
        var connection = new HubConnectionBuilder()
           .WithUrl("http://localhost:61514/notifications")

           .Build();


        connection.On<NotificationData>("Notification", (notificationData) =>
            Console.WriteLine($"Somebody connected: {notificationData.ClientId}"));

        connection.StartAsync().GetAwaiter().GetResult();

        Console.WriteLine("Listening. Press a key to quit");
        Console.ReadKey();

这是带有映射的 Web 应用程序的启动:

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddSignalR();
        services.AddControllers();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<NotificationHub>("/Notifications");
        });
    }

我不断收到此错误:System.IO.IOException:“在握手开始之前服务器已断开连接。” 我一定会在这里遗漏一些东西。

更新:
打开日志并收到此错误:

dbug:Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[8] 在“ http://localhost:61514/notifications ”处与服务器建立连接。dbug:Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[9] 与服务器建立连接“BdROAEEQnGUeDYAW5EspRA”。dbug:Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[7] 使用 Url 启动传输“ServerSentEvents”:http://localhost:61514/notifications. 信息:Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[1] 开始传输。传输方式:文本。dbug:Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[3] 开始接收循环。dbug:Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[9] 收到 30 个字节。解析 SSE 帧。dbug:Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[4] 接收循环已停止。dbug:Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[100] 开始发送循环。dbug:Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[18] 传输“ServerSentEvents”已启动。调试:Microsoft.AspNetCore.Http.Connections.Client.Internal。ServerSentEventsTransport[102] 发送循环已取消。dbug:Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[101] 发送循环已停止。未处理的异常。信息:Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[3] HttpConnection 已启动。信息:Microsoft.AspNetCore.SignalR.Client.HubConnection[24] 使用 HubProtocol 'json v1'。System.IO.IOException:在握手开始之前服务器断开连接。在 Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancelToken) 在 Microsoft.AspNetCore.SignalR.Client.HubConnection 的 Microsoft.AspNetCore.SignalR.Client.HubConnection.HandshakeAsync(ConnectionState startingConnectionState, CancellationToken cancelToken)。

标签: signalrasp.net-core-signalrsignalr-client

解决方案


所以一整天都在扼杀这个问题后,我发现了问题所在,所以我想我会在这里发布解决方案,以防万一其他人遇到这个问题。

集线器端点指向控制器。因此,当客户端链接时,它两次击中控制器,导致服务器关闭连接。所以我改变了这一行:

app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<NotificationHub>("/Notify");
        });

从击中控制器的“/通知”到上面代码中的“通知”,将客户端从通知重新指向通知

 var connection = new HubConnectionBuilder()
           .WithUrl("http://localhost:61514/Notify")
          .ConfigureLogging(logging =>
          {
              logging.AddConsole();
              logging.SetMinimumLevel(LogLevel.Debug);
          })
           .Build();

并且消息开始流入。


推荐阅读