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.
TimeRelay
? IsTimeRelay
andTimeHub
in the same project? What is your expected result forTimeRelay
? In general,Clients.All.SendAsync
, it used to call clients methods intead of server methods. If you perfer to callTimeHub.UpdateTime
fromTimeRelay
, try registerTimeHub
class and callTimeHub.UpdateTime()
or, callReceiveMessage
directly fromTimeRelay
byawait context.Clients.All.SendAsync("ReceiveMessage", DateTime.Now.ToShortDateString());
. – GravityTimeRelay
from the HomeController. To answer you. Yes,TimeRelay
andTimeHub
are in the same project. I will try registeringTimeHub
. Also, I did try"ReceiveMessage"
inClients.All.SendAsync
, but it didn't work. – ChanteyTimeHub
in controllerindex
action, it will only work for the second request. I will keep checking this behavior. – GravityClients.All.SendAsync
will call the client method directly. However also mentioned above is instantiating the hub and calling hub methods manually. This is very wrong, never get a hub instance as it will not have the correct properties set up on it. If you want to call a "hub method" from your controller you'll need to refactor your code so the hub method and the controller call the same code, and then you can send to the client withClients.All.SendAsync
from your hub and controller with the data returned by your refactored method. – Fulguration