SignalR Core, not getting response from server when client is connected
Asked Answered
L

1

6

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:

enter image description here

Liddy answered 29/5, 2019 at 11:38 Comment(14)
Show the code how have you injected the NotificationsHub in your controller.Phillane
@Phillane i added Startup.cs too (only with signalR). Look into my editLiddy
What i know, when i have something like static Instance with { get; } = New it should work like singleton, in this case i wanted to achive always-on Hub to recive messages from Webapi when someone call Post actionLiddy
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. Is there a minimal demo that reproduces?Everyplace
Beacuse... it works! I just didnt know that while im debugging i cant acces into hub.On method... So, i need to close this question or just leave it to te next generations? You are right @itminus. I just lost a lot of time trying to debug itLiddy
:) That's really a question of Schrodinger .... I believe if you cannot reproduce the same issue, it's better to update your question to remind someone who wants to investigate. But don't remove this question in case that's a bug that we haven't realized for the present.Everyplace
I belive, you can post an answer. I will mark it, because it helps tbhLiddy
Could you tell me, your instance of VS debugger get into hubConnnection.On? Becuase i pupulated Notifications with updates from that method, and debugger when i posted a task didnt trigger my breakpoint, but Notifications list was populatedLiddy
@Liddy Yes. The breakpoint is triggered both in VS & VSCodeEveryplace
@Liddy When you say "didnt trigger my breakpoint", how do you configure the arguments of handler ? The number of arguments must be the same.Everyplace
I just set up breakpoint in hubConnection.On and it never trigger. When i just cheking, what is in Notifications, there was messages from Webapi sent by hubLiddy
Let us continue this discussion in chat.Everyplace
@Liddy Have you restarted the client when you debug?Everyplace
@Everyplace thanks for invest your time. Please, post answer so i will mark it as resolve for my problemLiddy
E
4

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:

  1. Your 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.
  2. 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.

  3. 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();
    
Everyplace answered 31/5, 2019 at 1:39 Comment(1)
Please, mention that my code works in your answer for the next generation of .NET developers (some of them diving straight into answers)Liddy

© 2022 - 2024 — McMap. All rights reserved.