0

我刚刚开始使用 SignalR,我想知道它是否是我正在处理的任务的好工具。

简而言之,我的对象具有随时间变化的属性。计时器作业每隔一段时间就会运行一次以更新这些属性。为了解释起见,假设我有一个带有属性“isExpired”的 MilkJugs,一旦某个 DateTime 被击中,该属性就会发生变化。

当我的 timerjob 碰到 MilkJug 并将其翻转为 isExpired = true 时,我希望所有客户端都能立即收到通知。如果客户在 Chrome 中查看七个 MilkJug,我希望他们看到所有七个 MilkJug 都变黄(或类似的东西)。

我可以使用 signalR 从 timerJob 向客户端“广播”这些通知吗?我刚刚浏览了他们提供的聊天示例,开始工作似乎超级简单......我想我可以做这样的服务器端:

public class ChatHub : Hub
{
    public void Send(List<MilkJugUpdate> updates)
    {
        // Call the broadcastMessage method to update milkJugs.
        Clients.All.broadcastMessage(updates);
    }
}

然后客户端只需遍历序列化数组,更新我的 JS viewModels 中的相应字段。

这听起来对吗?

4

2 回答 2

2

当然,ShootR已经做到了(HTML5 多人游戏)。这也在nuget的股票代码示例中完成。

最终,您可以在集线器之外获取集线器上下文并使用它来发送消息:

public void MyTimerFunction(object state)
{
    GlobalHost.ConnectionManager.GetHubContext<ChatHub>().Clients.All.broadcastMessage(updates);
}
于 2013-03-28T22:25:38.380 回答
2

你已经有了基本的想法。但是,您可能可以进行一些改进。

在这里,我假设您每次运行计时器作业时都会发送消息。这是没有必要的。如果发生变化,您只需要向客户发送消息。

首先,您可以处理 onconnected 事件,并发送牛奶罐的当前状态。

现在,当您运行计时器作业时,您只需在发生更改时调用 send。然后你将消息发送给客户,告诉他们发生了什么变化。在客户端,该函数处理如下更改

服务器

public class ChatHub : Hub
{
    public override Task OnConnected()
    {
        //some code here to fetch current state of jugs.
        return base.OnConnected();
    }        

    public void JugExpired(MilkJugUpdate update)
    {
        // Call the broadcastMessage method to update milkJugs.
        Clients.All.updateJug(update);
    }
}

客户

ChatHub.client.updateJug = function(update) {
    // code to update jug here
}

如果没有任何变化,这可以节省您向客户端发送消息的时间。

与另一个答案中指出的类似,您可以直接从计时器作业中调用客户端方法,但同样,我只建议发送更新,而不是每次都发送整个状态。

于 2013-03-28T22:28:01.500 回答