我刚开始使用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中的相应字段。
这听起来不错吗?
答案 0 :(得分:2)
当然,ShootR已经这样做了(HTML5多人游戏)。这也是在nuget上的Stock Ticker Sample中完成的。
最终,您可以在集线器之外获取集线器上下文并使用它来发送消息:
public void MyTimerFunction(object state)
{
GlobalHost.ConnectionManager.GetHubContext<ChatHub>().Clients.All.broadcastMessage(updates);
}
答案 1 :(得分: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
}
如果没有任何更改,这可以节省您向客户端发送邮件的信息。
与另一个答案中指出的类似,您可以直接从计时器作业调用客户端方法,但同样,我只建议每次发送更新,而不是整个状态。
答案 2 :(得分:0)
查看this example如何将数据从服务器推送到客户端