【问题标题】:Server function to be ran once for all users为所有用户运行一次服务器功能
【发布时间】:2019-03-01 21:18:16
【问题描述】:

晚上好,

在我的 SignalR 应用程序中,我有一个“同时”为所有用户运行的 javascript 计时器。在这个计时器结束时,一个服务器函数被调用,这就是这个问题的开始。 由于该函数在计时器结束时调用,因此每个连接的用户都会同时调用它,这是不必要的,因为它将为所有连接的用户返回相同的输出。作为一个逻辑上复杂的功能,让服务器为所有用户不必要地运行它会造成很大的资源浪费。

我怎样才能让它只运行一次(可能是第一次调用它(直到下一个计时器停止))?

提前谢谢你

【问题讨论】:

  • 您可以使用静态布尔变量来跟踪这一点。将变量默认为 false 并在第一次执行时将其设置为 true。如果此 bool 设置为 true 以供将来执行,则忽略执行。或者在您设置的数据库中保留一个标志,并使用上述相同的逻辑进行检查。
  • @JakoBasson 谢谢。我考虑了数据库解决方案,但认为这会浪费资源(不确定是否发出所有这些请求只是为了了解这样的状态会在现实世界中产生影响)。静态变量听起来像我要找的东西,但老实说,我对这些状态变量并不是很熟悉,它是在类中声明为静态的变量吗?
  • 它是在类中声明为静态的变量吗?是的。这是一个可能对您有帮助的链接:stackoverflow.com/questions/14154892/…
  • @JakoBasson 非常感谢。这解决了很多问题。我什至不知道我怎么会对这么简单的方面一无所知

标签: c# asp.net signalr signalr-2


【解决方案1】:

您可以使用GlobalHost.ConnectionManager.GetHubContext。这将允许您获取任何集线器上下文,然后在该上下文上触发 Clients.All.YourFunction。这将向订阅该集线器的所有连接客户端发送发送消息。

你需要有一个后台进程在你的 JavaScript 函数触发时运行(顺便说一下,依靠你的所有客户端同时调用一个 JavaScript 函数确实不是一个好主意;不同的客户端位置和不同的机器性能意味着它们不可能同时发生)。

以下假设您只是在单个服务器上运行它。如果您要将其部署到网络场,那么您需要使用 Database 值来确保您不会重复相同的工作,或者设置一个特定的服务器实例来负责执行调用(否则你最终会在每台服务器上调用一次)。

创建一个在后台运行的进程(我在这里坚持一个简单的线程,我实际上为此使用了 HangFire,但这对于示例来说就足够了),例如在 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"
};

【讨论】:

  • *这听起来像是一个解决方案。虽然我已经通过它的根解决了这个问题,但使用静态变量来创建一个服务器计时器(它与向用户显示的 javascript 同时启动),然后让服务器在计时器结束时调用它,因此函数是只调用一次
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-14
  • 2019-05-13
  • 2018-06-21
相关资源
最近更新 更多