Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR message not being received on the client

Tags:

c#

wcf

wpf

signalr

I've been trying to get my WPF client app to receive a SignalR message sent by the WCF service. I've tried many things and have now resorted to hacking away in the hopes that something just works. I've followed tutorials and examples online, and I simply can't get my WPF OnSignalRMessage() method to get called. Where am I going wrong here?

My hub:

public class PrestoHub : Hub
{
    public void Send(string message)
    {
        Clients.All.OnSignalRMessage(message);
    }
}

My startup class:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HubConfiguration { EnableCrossDomain = true };

        app.MapHubs("http://localhost:8084", config);
    }
}

The method that starts my SignalR host (within my WCF service host):

    private void StartSignalRHost()
    {
        const string url = "http://localhost:8084";
        WebApplication.Start<Startup>(url);
    }

The code to actually send some message:

GlobalHost.ConnectionManager.GetHubContext<PrestoHub>().Clients.All.OnSignalRMessage("snuh");
Console.WriteLine("Sent 'snuh' to all clients...");

My WPF client methods:

    private void InitializeSignalR()
    {
        var hubConnection = new Connection("http://localhost:8084");
        hubConnection.Start();
        hubConnection.Received += OnSignalRMessage;
    }

    private void OnSignalRMessage(string data)
    {
        MessageBox.Show(data);
    }
like image 824
Bob Horn Avatar asked May 25 '13 20:05

Bob Horn


People also ask

How do I send a message to particular client in SignalR?

public async Task BroadcastToUser(string data, string userId) => await Clients. User(userId). SendAsync("broadcasttouser", data); Remember that when we are sending messages to a user, they will be sent to all connections associated with that user and not just any particular connection.

Does SignalR require sticky session?

SignalR requires that all HTTP requests for a specific connection be handled by the same server process. When SignalR is running on a server farm (multiple servers), "sticky sessions" must be used. "Sticky sessions" are also called session affinity by some load balancers.

Does SignalR guarantee delivery?

SignalR doesn't guarantee message delivery. Since SignalR doesn't block when you call client methods, you can invoke client methods very quickly as you've discovered. Unfortunately, the client might not always be ready to receive messages immediately once you send them, so SignalR has to buffer messages.

How many connections SignalR can handle?

In the default mode, the app server creates five server connections with Azure SignalR Service. The app server uses the Azure SignalR Service SDK by default. In the following performance test results, server connections are increased to 15 (or more for broadcasting and sending a message to a big group).


1 Answers

While I'm still struggling to understand the how and why, I was able to get it working. +1 to N. Taylor Mullen for pointing me in the right direction. In addition to his suggestion on the client side, I had to change some server code as well, namely using an empty hub and a simplified Startup class.

My hub:

public class PrestoHub : Hub{}

Note: The hub is empty because we're not calling methods within it. As we'll see later, we get the hub context and send messages to the clients.

My startup class:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapHubs();
    }
}

The above code seems to be what fixed the problem. This also works:

var config = new HubConfiguration { EnableCrossDomain = true };
app.MapHubs(config);

But as soon as I specify a URL, my client doesn't receive the messages (tried with and without the "SignalR" part):

app.MapHubs("http://localhost:8084/SignalR", config);

The method that starts my SignalR host (within my WCF service host):

private void StartSignalRHost()
{
    const string url = "http://localhost:8084";
    WebApplication.Start<Startup>(url);
}

The code to actually send some message:

var hubContext = GlobalHost.ConnectionManager.GetHubContext<PrestoHub>();
hubContext.Clients.All.OnSignalRMessage("snuh");

My WPF client method:

private void InitializeSignalR()
{
    var hubConnection = new HubConnection("http://localhost:8084");
    var prestoHubProxy = hubConnection.CreateHubProxy("PrestoHub");
    prestoHubProxy.On<string>("OnSignalRMessage", (data) =>
        {
            MessageBox.Show(data);
        });
    hubConnection.Start();
}
like image 134
Bob Horn Avatar answered Oct 14 '22 02:10

Bob Horn