WPF SignalR server returns HTTP 400 Bad Request (Invalid host address)
Asked Answered
F

1

6

I'm trying to set up a SignalR hub to be able to push notifications to a bunch of WPF clients over the web. I've tried to follow the basic guidelines and tutorials and have created a WPF SignalR Server (for testing purposes only). This has been put on a server in my LAN and this is how it looks:

Startup.cs

class Startup
{
    public void Configuration(IAppBuilder app)
    {
        HubConfiguration hc = new HubConfiguration();
        hc.EnableDetailedErrors = true;

        app.UseCors(CorsOptions.AllowAll);
        app.MapSignalR(hc);
    }
}

MainWindow.xaml.cs

public IDisposable SignalR { get; set; }
const string ServerURI = "http://localhost:8554";

private void StartServer()
{
    try
    {
        SignalR = WebApp.Start(ServerURI);
    }
    catch (TargetInvocationException)
    {
        WriteToConsole("A server is already running at " + ServerURI);
        return;
    }
    this.Dispatcher.Invoke(() => btnStopHub.IsEnabled = true);
}

AdHocHub.cs

public class AdHocHub : Hub
{
    public void Send(string data)
    {
        Clients.All.notifyData(data);
    }

    public override Task OnConnected()
    {
        Application.Current.Dispatcher.Invoke(() => 
            ((MainWindow)Application.Current.MainWindow).WriteToConsole("Client connected: " + Context.ConnectionId));
        return base.OnConnected();
    }

    public Task OnDisconnected()
    {
        Application.Current.Dispatcher.Invoke(() =>
            ((MainWindow)Application.Current.MainWindow).WriteToConsole("Client disconnected: " + Context.ConnectionId));

        return base.OnDisconnected(true);
    }
}

The server starts just fine. However when I try to connect a client to it it refuses giving me a 400 - Bad Request. If I try to navigate to http://192.nnn.nnn.nnn/signalr all I get is Bad Request - Invalid Hostname. If I run the server and the client on the same machine Everything works just as it should. What am I doing wrong here?

The client calls are set up like this:

private async void ConnectAsync()
{
    Connection = new HubConnection(ServerURI);
    HubProxy = Connection.CreateHubProxy("AdHocHub");
    HubProxy.On<string>("notifyData", (notifyData) => this.Dispatcher.Invoke(() => txtEvents.AppendText(notifyData.ToString())));

    try
    {
        await Connection.Start();
    }
    catch (HttpRequestException ex)
    {
        MessageBox.Show(ex.ToString());
        lblStatus.Content = "Unable to connect to server: Start server before connecting clients.";
        return;
    }
    txtEvents.AppendText("Connected to server and listening...");
}

I've tried changing the URI in the server from hostname to its IP, but then I just get a TargetInvocationException, so that won't help.

As stated earlier, this entire setup seems to work fine so long as the client and server runs on the same machine, but not once I move it even though I've set the CorsOptions to AllowAll.

Fitz answered 3/2, 2015 at 13:11 Comment(6)
Change ServerURI in server from localhost to http://+:8554. Else it will listen for localhost only. It works in same machine because its localhost. But as soon as you change it to this new scheme, you'll need visual studio running in admin mode, else TargetInvocationException will be raised if UAC is on.Pasqualepasqueflower
That worked like a charm. HUGE thanks for solving this headache for me. Add it as a reply and I'll check it as solved. :)Fitz
@Mathew what kinds of permissions does the user running the process need to be able to host to the http://+:port address?Berberidaceous
@Berberidaceous you can allow non-administrators to listen using netshPasqualepasqueflower
I was running into the same issue with the server running as a service. I was using the .LocalService on the localhost. I had overlooked that when I moved it to a remote server. I ended up using a .User account with privs to get the job done along with http://+:<portnumber> for it to run correctly.Recurve
Wow, @MatJ 's answer on http://+:8554 is so underrated. It should be put as an ANSWER !!! THANKS!!! I am running the hub in Azure Virtual Machine.Lorrin
P
3

(Converting my own comment to an answer since it seems to be the answer in most cases)

Change ServerURI in server from localhost to http://+:8554, else it will listen for localhost only. It works in same machine because its localhost.

But as soon as you change it to this new scheme, while debugging, you'll need visual studio running in admin mode or else TargetInvocationException will be thrown if UAC is on.

Pasqualepasqueflower answered 6/12, 2018 at 8:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.