无法让 SignalR Hub 变量停止丢失值(静态变量不是问题)
Can't get SignalR Hub variables to stop losing value (static variables not the issue)
我有一个简单的 SignalR 服务器,我几乎没有使用它的经验。
我的中心 class 是:
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
}
}
这里是我在代码中调用 Searching 方法和变量的地方
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);
}
在 MyHub class 中,我希望玩家列表(目前)跟踪每次有人单击客户端上的 btnSearch,这样做我只是添加了一个玩家成员class 到 MyHub 中的玩家列表。
出于某种原因,每次我调用它时,使用调试器我都可以看到列表再次为空,再次调用构造函数,玩家列表再次为空。
我在其他堆栈溢出问题中看到问题是静态变量,但我的问题不是静态的。 (播放器 class 中也没有任何内容是静态的)
基本上,集线器是暂时的,这意味着您无法知道某个实例何时会被回收或丢弃。解决这个问题的一种方法是对状态使用单例,但有很多选择。这直接来自 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"
我有一个简单的 SignalR 服务器,我几乎没有使用它的经验。
我的中心 class 是:
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
}
}
这里是我在代码中调用 Searching 方法和变量的地方
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);
}
在 MyHub class 中,我希望玩家列表(目前)跟踪每次有人单击客户端上的 btnSearch,这样做我只是添加了一个玩家成员class 到 MyHub 中的玩家列表。
出于某种原因,每次我调用它时,使用调试器我都可以看到列表再次为空,再次调用构造函数,玩家列表再次为空。
我在其他堆栈溢出问题中看到问题是静态变量,但我的问题不是静态的。 (播放器 class 中也没有任何内容是静态的)
基本上,集线器是暂时的,这意味着您无法知道某个实例何时会被回收或丢弃。解决这个问题的一种方法是对状态使用单例,但有很多选择。这直接来自 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"