晚上好,
在我的 SignalR 应用程序中,我有一个“同时”为所有用户运行的 javascript 计时器。在这个计时器结束时,一个服务器函数被调用,这就是这个问题开始的地方。由于该函数在计时器结束时调用,因此每个连接的用户都会同时调用它,这是不必要的,因为它将为所有连接的用户返回相同的输出。作为一个逻辑上复杂的功能,让服务器为所有用户不必要地运行它会造成很大的资源浪费。
我怎样才能使它只运行一次(可能是第一次调用它(直到下一个计时器停止))?
先感谢您
你可以利用GlobalHost.ConnectionManager.GetHubContext
. 这将允许您获取任何集线器上下文,然后Clients.All.YourFunction
在该上下文上触发。这将向订阅该集线器的所有连接客户端发送消息。
您将需要有一个后台进程,在您的 JavaScript 函数触发时运行(顺便说一下,依赖所有客户端同时调用 JavaScript 函数确实不是一个好主意;不同的客户端位置和不同的机器性能将意味着它们不太可能同时发生)。
以下假设您只是在单个服务器上运行它。如果您要将其部署到网络场,那么您将需要使用 Database 值来确保您不会重复相同的工作,或者设置一个特定的服务器实例来负责执行调用(否则你最终会在每台服务器上打一个电话)。
创建一个在后台运行的进程(我在这里坚持一个简单的线程,我实际上为此使用了 HangFire,但这对于示例来说就足够了),例如 On App_Start
Thread thread = new Thread(new ThreadStart(YourFunction));
thread.Start();
然后创建YourFunction
将负责您的客户呼叫:
private bool Cancel = false;
private void YourFunction()
{
do
{
string foo = "Foo";
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<YourHub>();
context.Clients.All.SendYourMessage(foo);
Thread.Sleep(10000);
}
while(!Cancel)
}
然后在客户端,只需处理来自集线器的消息:
youyHub.client.sendYourMessage = function(message)
{
// message == "Foo"
};