dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.37k stars 9.99k forks source link

SignalR Core, not getting response from server when client is connected #10617

Closed michasacuer closed 5 years ago

michasacuer commented 5 years ago

I just copy-pasted my stack overflow question from here. I belive its uncommon problem, because yesterday these snippets worked perfectly. In two machines with Visual Studio 2017 and Visual Studio 2019 that code stopped working

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.

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"));
        }

Here is connection that i can get it, when my client WPF will register his connection:

enter image description here

BrennanConroy commented 5 years ago

From your code, you aren't storing the HubConnection anywhere. So the Garbage Collector is free to clean it up whenever it wants after Initialize() is called.

michasacuer commented 5 years ago

Everything works fine, i didnt know that i cant acces to hub.On methods. Messages adding to Notifications works, but i could not debug it.