0
votes

I'm trying to use SignalR to distribute status updates to listening clients. However my clients are failing with "404 Not found" when attempting to start the connection.

I've used https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc as a starting point, although I want a C# client not a scripted web page.

I've completed the following steps for the hub:

  1. AspNet Web Application (.Net Framework 4.5.2) added to solution
  2. SignalR Hub class added
  3. Owin start-up class added
  4. Application created under IIS virtual path /MyService .Net CLR version 4.0 Integrated Managed Pipeline Service account identity
  5. Client created with connection code as shown

For the most part my testing has revolved around trying the two different connection classes (Connection and HubConnection) using a variety of different URL.

The server side uses a hub and Microsoft.AspNet.SignalR version 2.4.1 library

using Microsoft.AspNet.SignalR;

namespace MyService
{
    public class JobStatusHub : Hub
    {
        public void Send(string name, string message)
        {
            Clients.All.broadcastMessage(name, message);
        }
    }
}

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(MyService.Startup))]

namespace MyService
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {          
            app.MapSignalR();
        }
    }
}

There will be two types of clients; message providers and message consumers. So far I have only worked on a message source which contains the following code using Microsoft.AspNet.SignalR.Client version 2.4.1

        var connection = new Connection("http://localhost/MyService/signalr/");
        connection.Credentials = CredentialCache.DefaultCredentials;
       connection.Start().Wait();

And also

        var connection = new HubConnection("http://localhost/MyService/signalr");
        connection.Credentials = CredentialCache.DefaultCredentials;
        connection.Start().Wait();

I have tried a variety of connection strings

Interesting aside: when I attempt to connect to a .Net CORE hub using

        var connection = new Connection("http://localhost/MyCoreService/myHub");
        connection.Credentials = CredentialCache.DefaultCredentials;
        connection.Start().Wait();

The client appears to get further as it throws

StatusCode: 405, ReasonPhrase: 'Method Not Allowed'

Does anyone have any suggestions as to what might resolve this “404 Not found” error? Or am I making a mistake not using a CORE service and hub (when I looked up the Method Not Allowed error the results suggested I couldn’t use a Framework 2.4.1 client with a CORE hub)?

2
You cannot mix CORE Server/Clients with .NET (2.4.1)Server/Clients, they are not compatible with each other. Either are perfectly viable depending on your needs. - Frank M
Thank you @FrankM - that confirms what I thought about the problem when I tried a CORE hub (mentioned in the aside at the end). Can you offer any ideas on what's going wrong here as I'm using Framework 4.5 for both client and server sides? - treviski
Out of desperation I'm trying random parameters in some of the key calls. For one example (out of many attempts) I tried app.MapSignalR("localhost/myServer/jobStatusHub"); together with var connection = new HubConnection("localhost/myServer"); and var hubProxy = connection.CreateHubProxy("/jobStatusHub"); - treviski

2 Answers

0
votes

Before you can establish a connection, you have to create a HubConnection object and create a proxy.

Otherwise your client doesn't know about your JobStatusHub.

var hubConnection = new HubConnection("http://localhost/MyService/signalr/");
IHubProxy proxy = hubConnection.CreateHubProxy("JobStatusHub");
await hubConnection.Start();

Side note: Using .Wait(); is bad practice. The use of GetAwaiter().GetResult(); is preferred as this avoids the AggregateException wrapping that happens if you use Wait() or Result.

0
votes

OK, this isn't a solution as such but I did eventually get things working. First I threw away my project and started again, this time using https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr and SignalR Console app example

as my starting points. The hub looked much the same but the client was changed to look like

private static async void SendMsg ()
{
    var hub = new HubConnection("http://localhost:6692");
    var proxy = hub.CreateHubProxy("ChatHub");
    await hub.Start().ContinueWith(task =>
    {
        if (task.IsFaulted)
            Console.WriteLine($"Failed to connect due to task.Exception.GetBaseException()}");
        else
            Console.WriteLine($"Connected: {task.Status}");
    });
    await proxy.Invoke<string>("Send", "Console", "Testing");
    Console.WriteLine("SendMsg finished");
}

My next job will be to turn this very simple PoC code into something more functional as part of my solution.