将 SignalR 注入核心 WorkerService
Injecting SignalR into a Core WorkerService
我正在尝试将 SignalR
注入到 WorkerService
项目中,然后模拟服务器端通知。
在我的 Worker.cs
文件中,我得到一些空引用 - 这告诉我最初我的 Hub 对象不正确。
我先用同名项目创建了一个NotificationHub solution
。
这是 Notifications.cs
- 效果很好。
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NotificationHub.Hubs
{
public interface IHubClient
{
Task MessageReceived(string user, string message);
Task MessageReceived(string message);
}
public class Notifications: Hub<IHubClient>
{
[HubMethodName("SendMessageToClient")]
public async Task SendMessage(string username, string message)
{
await Clients.All.MessageReceived(username, "from Notification Hub:" + message);
}
public override Task OnConnectedAsync()
{
Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
_ = SendMessage("From Server", "Hub reconnected on server.");
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
Console.Write("Hub just disconnected on server.");
return base.OnDisconnectedAsync(exception);
}
}
}
NotificationHub
在我本地机器上的 IIS 中运行,让我从我的 TypeScript
客户端调用通知中心。
即我只是添加了一个简单的 HTML button
来触发来自客户端的消息。我的函数触发:
this.hubConnection.send('SendMessageToClient', 'client', `Message from client side. ${today}`)
.then(() => console.log('Message sent from client.'));
Core WorkerService:我的问题就在这里
然后我添加了一个 NotificationWorkService,我试图在其中注入 SignalR。目标是最终在 Windows 服务器上提供此服务 运行,该服务器会定期检查通知,并将它们传送到浏览器。
在我的 WorkerService 项目中,这里是 Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace HarmonyNotificationWorkerService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
}
这里是 Worker.cs
-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NotificationHub.Hubs;
namespace HarmonyNotificationWorkerService
{
public interface IHubClient
{
Task MessageReceived(string user, string message);
Task MessageReceived(string message);
}
public class Worker : BackgroundService
{
private IHubContext<Notifications> _hubContext;
private readonly Hub<IHubClient> _hubNotif;
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using (var hubConnection = new HubConnection("/hub"))
{
IHubProxy hubproxy = hubConnection.CreateHubProxy("https://localhost:44311/hub");
await hubproxy.Invoke("SendMessage", "test");
}
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
private async Task CheckForNotifications()
{
await _hubNotif.Clients.All.MessageReceived("from work server", "Dude, you've got mail!");
}
}
}
问题:
问题是 _hubContext
和 _hubNotif
对象总是空的,所以我无法测试其中任何一个。我最初没有正确定义它们,但我不确定该怎么做。 C# 还向我显示有关此空引用的警告。
System.InvalidOperationException: 'Data cannot be sent because the connection is in the disconnected state. Call start before sending any data.`
更新 - 安装 SIGNALR 客户端程序包
我在Worker.cs
中添加了using Microsoft.AspNetCore.SignalR.Client;
,并在Worker
class的顶部设置了一个 private readonly HubConnection _hubConnection;
。
然后我修改了下面的方法来检查conn状态,然后发送消息:
private async Task CheckForNotifications()
{
if (_hubConnection.State == HubConnectionState.Disconnected)
{
await _hubConnection.StartAsync();
}
_ = _hubConnection.SendAsync("SendMessageToClient", "from service worker", "You've got mail!");
}
一切似乎都很顺利。
线程有时会以 code 0
退出,但我相信在这种情况下这是正常的,因为我在 Task.Delay(5000);
上 运行
不要混合使用 ASP.NET SignalR 和 ASP.NET Core SignalR。它们彼此不相容。您的服务器正在使用 ASP.NET Core SignalR,因此您的工作人员应该使用 HubConnectionBuilder
.
创建一个 HubConnection
我正在尝试将 SignalR
注入到 WorkerService
项目中,然后模拟服务器端通知。
在我的 Worker.cs
文件中,我得到一些空引用 - 这告诉我最初我的 Hub 对象不正确。
我先用同名项目创建了一个NotificationHub solution
。
这是 Notifications.cs
- 效果很好。
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace NotificationHub.Hubs
{
public interface IHubClient
{
Task MessageReceived(string user, string message);
Task MessageReceived(string message);
}
public class Notifications: Hub<IHubClient>
{
[HubMethodName("SendMessageToClient")]
public async Task SendMessage(string username, string message)
{
await Clients.All.MessageReceived(username, "from Notification Hub:" + message);
}
public override Task OnConnectedAsync()
{
Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
_ = SendMessage("From Server", "Hub reconnected on server.");
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
Console.Write("Hub just disconnected on server.");
return base.OnDisconnectedAsync(exception);
}
}
}
NotificationHub
在我本地机器上的 IIS 中运行,让我从我的 TypeScript
客户端调用通知中心。
即我只是添加了一个简单的 HTML button
来触发来自客户端的消息。我的函数触发:
this.hubConnection.send('SendMessageToClient', 'client', `Message from client side. ${today}`)
.then(() => console.log('Message sent from client.'));
Core WorkerService:我的问题就在这里
然后我添加了一个 NotificationWorkService,我试图在其中注入 SignalR。目标是最终在 Windows 服务器上提供此服务 运行,该服务器会定期检查通知,并将它们传送到浏览器。
在我的 WorkerService 项目中,这里是 Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace HarmonyNotificationWorkerService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
}
这里是 Worker.cs
-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NotificationHub.Hubs;
namespace HarmonyNotificationWorkerService
{
public interface IHubClient
{
Task MessageReceived(string user, string message);
Task MessageReceived(string message);
}
public class Worker : BackgroundService
{
private IHubContext<Notifications> _hubContext;
private readonly Hub<IHubClient> _hubNotif;
private readonly ILogger<Worker> _logger;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using (var hubConnection = new HubConnection("/hub"))
{
IHubProxy hubproxy = hubConnection.CreateHubProxy("https://localhost:44311/hub");
await hubproxy.Invoke("SendMessage", "test");
}
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
private async Task CheckForNotifications()
{
await _hubNotif.Clients.All.MessageReceived("from work server", "Dude, you've got mail!");
}
}
}
问题:
问题是 _hubContext
和 _hubNotif
对象总是空的,所以我无法测试其中任何一个。我最初没有正确定义它们,但我不确定该怎么做。 C# 还向我显示有关此空引用的警告。
System.InvalidOperationException: 'Data cannot be sent because the connection is in the disconnected state. Call start before sending any data.`
更新 - 安装 SIGNALR 客户端程序包
我在Worker.cs
中添加了using Microsoft.AspNetCore.SignalR.Client;
,并在Worker
class的顶部设置了一个 private readonly HubConnection _hubConnection;
。
然后我修改了下面的方法来检查conn状态,然后发送消息:
private async Task CheckForNotifications()
{
if (_hubConnection.State == HubConnectionState.Disconnected)
{
await _hubConnection.StartAsync();
}
_ = _hubConnection.SendAsync("SendMessageToClient", "from service worker", "You've got mail!");
}
一切似乎都很顺利。
线程有时会以 code 0
退出,但我相信在这种情况下这是正常的,因为我在 Task.Delay(5000);
不要混合使用 ASP.NET SignalR 和 ASP.NET Core SignalR。它们彼此不相容。您的服务器正在使用 ASP.NET Core SignalR,因此您的工作人员应该使用 HubConnectionBuilder
.
HubConnection