0

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://learn.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)?

treviski
  • 1
  • 1
  • 1
  • 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 Aug 07 '19 at 12:35
  • 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 Aug 07 '19 at 12:58
  • 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("http://localhost/myServer"); and var hubProxy = connection.CreateHubProxy("/jobStatusHub"); – treviski Aug 14 '19 at 11:02

2 Answers2

0

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.

bdongus
  • 658
  • 4
  • 20
  • Thank you for the feedback. I tried a HubConnection with a HubProxy using URLs http://localhost/MyService/signalr/ and http://localhost/MyService/signalr/hubs but both continued to give me 404 Not found errors. Is my server side call app.MapSignalR(); enough to identify the jobStatusHub? – treviski Aug 07 '19 at 13:59
  • As long as your server project's url is "http://localhost/MyService", yes. Otherwise you have to provide MapSignalR the real url or adjust your connection url on the client side. – bdongus Aug 08 '19 at 14:08
  • no joy I'm afraid. I've been tinkering with the parameters on the new HubConnection and CreateHubProxy commands on the client and the app.MapSignalR on the server but to no useful effect. – treviski Aug 14 '19 at 10:59
  • And what message or error do you see? Can you add your new code to your post? – bdongus Aug 22 '19 at 03:56
0

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://learn.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.

treviski
  • 1
  • 1
  • 1