I'm a newb to SignalR. I'm trying to set up a Asp.Net Core WebAPI so that other clients can connect to it using SignalR and get real-time data. My Hub class is:
public class TimeHub : Hub
{
public async Task UpdateTime(string message)
{
await Clients.All.SendAsync("ReceiveMessage", message);
}
}
I have a relay class as follows:
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);
}
});
}
}
Startup class:
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();
}
The client is a console application and the code is:
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}");
}
}
I tried debugging the application. The client got connected to the TimeHub
succesfully. The no of connections in Clients.All
changed from 0 to 1, when the client got connected. But, when await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
is executed, the UpdateTime
function in TimeHub
is not getting executed and the client is not getting any message.
I tried using "UpdateTime"
, "SendMessage"
, and "ReceiveMessage"
as method in Clients.All.SendAsync
in TimeRelay
class. Nothing worked. Could someone point out my mistake in this.
I got it to work and thought I will answer it here. Thanks @TaoZhou for the tip.
My mistake was sending "UpdateTime" from server and waiting on "ReceiveMessage" at the client.
Ideally the code should look like the following:
SignalR Server:
await context.Clients.All.SendAsync("UpdateTime", DateTime.Now.ToShortDateString());
SignalR Client:
var on = hubConnection.On("UpdateTime", OnReceivedAction);
In this case any message send from the server would be received at the client instantly.
Please refer the code provided in the question for more info.