我有一个简单的SignalR服务器,我几乎没有经验。
我的中心课程是:
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
}
}
我在这里调用搜索方法和代码中的变量
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类中,我希望玩家列表(现在)每次有人点击客户端上的btnSearch时都会跟踪,通过这样做,我只是将Player类的成员添加到玩家列表中MyHub。
出于某种原因,每次我调用它时,使用调试器我可以看到列表再次为null,再次调用构造函数,并且播放器列表再次为空。
我在其他堆栈溢出问题中看到问题是静态变量,但我的内容中没有任何内容是静态的。 (Player类中的任何内容都不是静态的)
答案 0 :(得分:2)
基本上,集线器是瞬态的,这意味着您无法知道何时将回收或丢弃实例。解决这个问题的一种方法是使用Singleton作为状态,但有很多选择。这直接来自MSDN [1]:
“您没有实例化Hub类或从您自己的方法调用其方法 服务器上的代码;所有这些都由SignalR Hubs为您完成 管道。 SignalR每次都会创建一个Hub类的新实例 它需要处理Hub操作,例如客户端连接时, 断开连接,或对服务器进行方法调用。
由于Hub类的实例是瞬态的,因此您无法使用它们 保持状态从一个方法调用到下一个。每一次 服务器接收来自客户端的方法调用,一个新的实例 Hub类处理消息。通过多重维持状态 连接和方法调用,使用一些其他方法,如a 数据库,或Hub类上的静态变量,或其他类 这不是来自Hub。如果您将数据保留在内存中,请使用 方法如Hub类上的静态变量,数据将是 应用程序域回收时丢失。
如果要根据自己运行的代码向客户端发送消息 在Hub类之外,您无法通过实例化Hub类来实现 例如,你可以通过获取SignalR的引用来实现 Hub类的上下文对象。有关更多信息,请参见如何 稍后调用客户端方法并从Hub类外部管理组 在这个主题中。“
[1]: https://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server “SignalR文档”