SignalR 核心控制台客户端未收到通知
SignalR core console client not receiving notifications
我看了一些类似的问题,但没有弄清楚这个问题。我的 .NET 核心 Web API 项目中有一个简单的 Hub。这是中心:
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();
这是使用映射启动的网络应用程序:
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:'The server disconnected before the handshake could be started.'我一定是错过了一些东西。
更新:
打开日志并收到此错误:
dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[8]
Establishing connection with server at 'http://localhost:61514/notifications'.
dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[9]
Established connection 'BdROAEEQnGUeDYAW5EspRA' with the server.
dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[7]
Starting transport 'ServerSentEvents' with Url: http://localhost:61514/notifications.
info: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[1]
Starting transport. Transfer mode: Text.
dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[3]
Starting receive loop.
dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[9]
Received 30 bytes. Parsing SSE frame.
dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[4]
Receive loop stopped.
dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[100]
Starting the send loop.
dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[18]
Transport 'ServerSentEvents' started.
dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[102]
Send loop canceled.
dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[101]
Send loop stopped.
Unhandled exception. info: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[3]
HttpConnection Started.
info: Microsoft.AspNetCore.SignalR.Client.HubConnection[24]
Using HubProtocol 'json v1'.
System.IO.IOException: The server disconnected before the handshake could be started.
at Microsoft.AspNetCore.SignalR.Client.HubConnection.HandshakeAsync(ConnectionState startingConnectionState, CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncInner(CancellationToken cancellationToken)
at System.Threading.Tasks.ForceAsyncAwaiter.GetResult()
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken)
at NotificationClient.Program.Main(String[] args)
所以在为这个问题烦恼了一整天之后,我发现了问题所在,所以我想我会 post 在这里找到解决方案,以防其他人遇到这个问题。
集线器端点指向控制器。因此,当客户端链接时,它会两次点击控制器,导致服务器关闭连接。所以我改变了这一行:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<NotificationHub>("/Notify");
});
从击中控制器的“/Notifications”到上面代码中的 "Notify",将客户端从 Notifications 重新指向 Notify
var connection = new HubConnectionBuilder()
.WithUrl("http://localhost:61514/Notify")
.ConfigureLogging(logging =>
{
logging.AddConsole();
logging.SetMinimumLevel(LogLevel.Debug);
})
.Build();
消息开始涌入。
我看了一些类似的问题,但没有弄清楚这个问题。我的 .NET 核心 Web API 项目中有一个简单的 Hub。这是中心:
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();
这是使用映射启动的网络应用程序:
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:'The server disconnected before the handshake could be started.'我一定是错过了一些东西。
更新:
打开日志并收到此错误:
dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[8] Establishing connection with server at 'http://localhost:61514/notifications'. dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[9] Established connection 'BdROAEEQnGUeDYAW5EspRA' with the server. dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[7] Starting transport 'ServerSentEvents' with Url: http://localhost:61514/notifications. info: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[1] Starting transport. Transfer mode: Text. dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[3] Starting receive loop. dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[9] Received 30 bytes. Parsing SSE frame. dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[4] Receive loop stopped. dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[100] Starting the send loop. dbug: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[18] Transport 'ServerSentEvents' started. dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[102] Send loop canceled. dbug: Microsoft.AspNetCore.Http.Connections.Client.Internal.ServerSentEventsTransport[101] Send loop stopped. Unhandled exception. info: Microsoft.AspNetCore.Http.Connections.Client.HttpConnection[3] HttpConnection Started. info: Microsoft.AspNetCore.SignalR.Client.HubConnection[24] Using HubProtocol 'json v1'. System.IO.IOException: The server disconnected before the handshake could be started. at Microsoft.AspNetCore.SignalR.Client.HubConnection.HandshakeAsync(ConnectionState startingConnectionState, CancellationToken cancellationToken) at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken) at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken) at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncInner(CancellationToken cancellationToken) at System.Threading.Tasks.ForceAsyncAwaiter.GetResult() at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken) at NotificationClient.Program.Main(String[] args)
所以在为这个问题烦恼了一整天之后,我发现了问题所在,所以我想我会 post 在这里找到解决方案,以防其他人遇到这个问题。
集线器端点指向控制器。因此,当客户端链接时,它会两次点击控制器,导致服务器关闭连接。所以我改变了这一行:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<NotificationHub>("/Notify");
});
从击中控制器的“/Notifications”到上面代码中的 "Notify",将客户端从 Notifications 重新指向 Notify
var connection = new HubConnectionBuilder()
.WithUrl("http://localhost:61514/Notify")
.ConfigureLogging(logging =>
{
logging.AddConsole();
logging.SetMinimumLevel(LogLevel.Debug);
})
.Build();
消息开始涌入。