I am working on a SignalR Clinet-Server connection. My server is WebApi Core 2.1
and my client is WPF .NET Framework 4.7.2
.
On the client side I have a singleton
hub service with one Instance to recive messages from server:
using System.Collections.ObjectModel;
using Microsoft.AspNetCore.SignalR.Client;
public class HubService
{
//singleton
public static HubService Instance { get; } = new HubService();
public ObservableCollection<string> Notifications { get; set; }
public async void Initialize()
{
this.Notifications = new ObservableCollection<string>();
var hubConnection = new HubConnectionBuilder()
.WithUrl(UrlBuilder.BuildEndpoint("Notifications"))
.Build();
hubConnection.On<string>("ReciveServerUpdate", update =>
{
//todo
});
await hubConnection.StartAsync();
}
}
i initialize it as singleton:
public MainWindowViewModel()
{
HubService.Instance.Initialize();
}
While I'm debugging, on MainWindowViewModel
im hitting that HubService
.
On Server
side its look like this.
Hub
:
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
public class NotificationsHub : Hub
{
public async Task GetUpdateForServer(string call)
{
await this.Clients.Caller.SendAsync("ReciveServerUpdate", call);
}
}
Im trigering send message in this way in my controller's methods:
[HttpPost]
public async Task<IActionResult> PostTask([FromBody] Task task)
{
if (!this.ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
this.taskService.Add(task);
//here im calling sending message. When im debugging
//i see one connection from my WPF with unique ConnectionId
await this.notificationsHub.Clients.All.SendAsync("ReciveServerUpdate", "New Task in database!");
return this.Ok(task);
}
As I wrote before, while I'm debugging my WebApi
, in Clients
I have exactly one connection from my WPF
. When I turn off WPF
, connection count = 0
so connections works perfectly.
But when I call SendAsync()
, I'm not reciving any information in WPF
in hubConnection.On
. Funny thing, yesterday it works perfectly.
So, is my thinking about making HubService
as static singleton
is right? If its, why i cant recive messages from WebApi
by SignalR
when my WPF
is connected to it?
I asked something similiar yesterday but i found a solution for it. Yesterday, my methods works, i could hit hubConnection.On
when i get any message from WebApi
. My question from yestarday.
EDIT
Injection of HUb
to controller:
private readonly ITaskService taskService;
private readonly IHubContext<NotificationsHub> notificationsHub;
public TaskController(ITaskService taskService, IHubContext<NotificationsHub> notificationsHub)
{
this.taskService = taskService;
this.notificationsHub = notificationsHub;
}
And Startup.cs
only SignalR
things (i deleted other things not related to signal):
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSignalR(routes => routes.MapHub<NotificationsHub>("/Notifications"));
}
EDIT2
Here is connection that i can get it, when my client WPF
will register his connection:
I tried your code with all kinds of clients (wpf/console/even with a browser), it always works fine for me. The hubConnection.On<string>("ReciveServerUpdate", update => {//todo});
always be invoked when I send a request to PostTask
.
I'm not sure why (sometimes) it doesn't work for you somehow . However, when SignalR client has connected to server but gets no message from server, there're possible two reasons:
PostTask([FromBody] Task task)
action method is not executed. Let's say this is an ApiController
method, if the browser posts a request with a Content-Type
of application/www-x-form-urlencoded
by accident, the invocation of Clients.All.SendAsync(..., ...);
won't be executed at all.The handler of SigalR client (hubConnection.On<>(method,handler)
) must has exactly the same argument list as the invocation in order to receive messages. We must be very careful when dealing with this.
Finally, it's better to add a reference to Microsoft.Extensions.Logging.Console
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.*" />
so that we could enable logging to troubleshoot :
var hubConnection = new HubConnectionBuilder()
.WithUrl(UrlBuilder.BuildEndpoint("Notifications"))
.ConfigureLogging(logging =>{
logging.AddConsole(); // enable logging
})
.Build();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With