DaMuffiner DaMuffiner - 1 month ago 15
C# Question

Can't get SignalR Hub variables to stop losing value (static variables not the issue)

I have a simple SignalR server, which I have almost no experience with.

My hub class is:

public class MyHub : Hub
{
public List<Player> players { get; set; }
public MyHub()
{
players = new List<Player>();
}
public void Searching(Player player)
{
players.Add(player);
//Clients.All.a
}
}


Here is where I call the Searching method and the variables in my code

public String UserName { get; set; }
public IHubProxy HubProxy { get; set; }
const string ServerURI = "http://localhost:5051/signalr";
public HubConnection Connection { get; set; }
public Player User { get; set; }

public MainWindow()
{
InitializeComponent();
User = new Player(100);
ConnectAsync();
}

private void btnSearch_Click(object sender, RoutedEventArgs e)
{
HubProxy.Invoke("Searching", User);
}


In MyHub class, I would like the players list to (for now) keep track of every time someone clicks the btnSearch on the client, and by doing this I am simply adding a member of the Player class to the players list in MyHub.

For some reason, every time I call this, using the debugger I can see that the list is null again, the constructor is called again, and the players list is empty again.

I've seen in other stack overflow questions that the problem is static variables, however nothing in mine is static. (Nothing in the Player class is static either)

Answer

Basically, hubs are transient, meaning you cannot know when an instance will be recycled or discarded. One way to solve this would be using a Singleton for the state, but there are many options. This is straight from MSDN [1]:

"You don't instantiate the Hub class or call its methods from your own code on the server; all that is done for you by the SignalR Hubs pipeline. SignalR creates a new instance of your Hub class each time it needs to handle a Hub operation such as when a client connects, disconnects, or makes a method call to the server.

Because instances of the Hub class are transient, you can't use them to maintain state from one method call to the next. Each time the server receives a method call from a client, a new instance of your Hub class processes the message. To maintain state through multiple connections and method calls, use some other method such as a database, or a static variable on the Hub class, or a different class that does not derive from Hub. If you persist data in memory, using a method such as a static variable on the Hub class, the data will be lost when the app domain recycles.

If you want to send messages to clients from your own code that runs outside the Hub class, you can't do it by instantiating a Hub class instance, but you can do it by getting a reference to the SignalR context object for your Hub class. For more information, see How to call client methods and manage groups from outside the Hub class later in this topic."

[1]: https://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server "SignalR documentation"