我是SignalR的新手。我正在尝试设置一个Asp.Net Core WebAPI,以便其他客户端可以使用SignalR连接到它并获取实时数据。 我的Hub类是:
public class TimeHub : Hub
{
public async Task UpdateTime(string message)
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
我有一个中继课程,如下所示:
public class TimeRelay : ITimeRelay
{
private readonly IHubContext<TimeHub> _timeHubContext;
public TimeRelay(IHubContext<TimeHub> context)
{
_timeHubContext = context;
Task.Factory.StartNew(async () =>
{
while (true)
{
await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
Thread.Sleep(2000);
}
});
}
}
启动类:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseSignalR((x) =>
{
x.MapHub<TimeHub>("/timeHub");
});
app.UseMvc();
}
客户端是一个控制台应用程序,代码为:
class Program
{
static Action<string> OnReceivedAction = OnReceived;
static void Main(string[] args)
{
Connect();
Console.ReadLine();
}
private static async void Connect()
{
var hubConnectionBuilder = new HubConnectionBuilder();
var hubConnection = hubConnectionBuilder.WithUrl("http://localhost:60211/timeHub").Build();
await hubConnection.StartAsync();
var on = hubConnection.On("ReceiveMessage", OnReceivedAction);
Console.ReadLine();
on.Dispose();
await hubConnection.StopAsync();
}
static void OnReceived(string message)
{
System.Console.WriteLine($"{message}");
}
}
我尝试调试该应用程序。客户端成功连接到TimeHub
。客户端建立连接后,Clients.All
中的连接数从0更改为1。但是,当执行await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
时,UpdateTime
中的TimeHub
函数没有得到执行,客户端也没有得到任何消息。
我尝试在类"UpdateTime"
中的"SendMessage"
中使用"ReceiveMessage"
,Clients.All.SendAsync
和TimeRelay
作为方法。没事。有人可以指出我对此的错误。
答案 0 :(得分:1)
对于Clients
,如果没有客户端连接到服务器,则它将为null。为了同时启动Asp.Net Core SignalR
和Console App
,Clients
可能为null,因为可以在Console App连接signalR服务器之前调用Index
。
尝试以下步骤:
更改TimeHub
public class TimeHub: Hub
{
public async Task UpdateTime(string message)
{
if (Clients != null)
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
}
注册TimeHub
services.AddSingleton<TimeHub>();
控制器
public class HomeController : Controller
{
private readonly TimeHub _timeHub;
public HomeController(TimeHub timeHub)
{
_timeHub = timeHub;
}
public IActionResult Index()
{
Task.Factory.StartNew(async () =>
{
while (true)
{
try
{
await _timeHub.UpdateTime(DateTime.Now.ToShortDateString());
Thread.Sleep(2000);
}
catch (Exception ex)
{
}
}
});
return View();
}
答案 1 :(得分:0)
我让它工作了,以为我会在这里回答。感谢@TaoZhou的提示。
我的错误是从服务器发送“ UpdateTime”并在客户端等待“ ReceiveMessage”。
理想情况下,代码应如下所示:
SignalR服务器:
await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
SignalR客户:
var on = hubConnection.On("UpdateTime", OnReceivedAction);
在这种情况下,从服务器发送的任何消息都会立即在客户端收到。
请参考问题中提供的代码以获取更多信息。