Search code examples
winformsasp.net-coresignalrhttp-status-code-404hub

Add SignalR to Net6 Web Api and connect from Winforms application (.net fx4.8) - hub not found


I'm trying to add signalr to the webapi, I create the CucinaHub class:

public class CucinaHub : Hub
{
    static ConcurrentDictionary<string, string> _users = new ConcurrentDictionary<string, string>();

    #region Client Methods

    public void SetUserName(string userName)
    {
        _users[Context.ConnectionId] = userName;
    }

    #endregion Client Methods
}

and configure SignalR:

services.AddSignalR();

app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapHub<CucinaHub>("/cucinahub");
        });

Then in Windows form application I use this code to connect with the hub:

        _signalRConnection = new HubConnection($"{Properties.Settings.Default.URL}/api", true);

        _hubProxy = _signalRConnection.CreateHubProxy("/cucinahub");

        _hubProxy.On("GetValvole", async () => await GetValvole());
        
        try
        {
            //Connect to the server
            await _signalRConnection.Start();
        }
        catch (Exception ex)
        {
            Log.Error(ex.ToString());
        }

I get always 404 response code:

Hosting environment: Development Content root path: D:\SwDev\PigsutffHTML\Server\Common\Common.WebApiCore Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down. info: Microsoft.AspNetCore.Hosting.Diagnostics[1] Request starting HTTP/1.1 GET http://localhost:5000/api/signalr/negotiate?clientProtocol=2.1&connectionData=[%7B%22Name%22:%22/cucinahub%22%7D] - - warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3] Failed to determine the https port for redirect. info: Microsoft.AspNetCore.Hosting.Diagnostics[2] Request finished HTTP/1.1 GET http://localhost:5000/api/signalr/negotiate?clientProtocol=2.1&connectionData=[%7B%22Name%22:%22/cucinahub%22%7D] - - - 404 0 - 122.4090ms

Where is the error? Thank you


Solution

  • The key is using the package Microsoft.AspNetCore.SignalR.Client on the WinForm project as client. It is available on .NETFramework. You can see from the picture here: enter image description here

    For testing purpose, I created one webapi project and another winform project. Winform project has been installed the package. Then you can follow the MS document to set up the hubs in webapi project.

    Then start the webapi project first to see which port it's running on. Now you can follow the MS Document for setting Clients to set client connect to hub. For testing purpose, I created two button functions to connect hub and send message to hub, here is the code of connect and send message function button:

    private void btnconnect_Click(object sender, EventArgs e)
        {
            try
            {
                connection.StartAsync().Wait();
            }
            catch (Exception ex)
            {
                //...
            }
        }
    
    private void btnsend_Click(object sender, EventArgs e)
        {
            try
            {
                 connection.InvokeAsync("SendMessage",
                    "winformclient", "hello world").Wait();
            }
            catch (Exception ex)
            {
                //...
            }
        }
    

    And here is the code for setting up client connecting(Remember using your own port here):

    HubConnection connection;
        public Form1()
        {
            InitializeComponent();
    
            connection = new HubConnectionBuilder()
                .WithUrl("https://localhost:7090/ChatHub")
                .Build();
    
            connection.Closed += async (error) =>
            {
                await Task.Delay(new Random().Next(0, 5) * 1000);
                await connection.StartAsync();
            };
        }
    

    Now start the WinForm Application, click the send button and you can get the result here: enter image description here

    You can see from the screenshot, the hub has already got the message from WinForm application.