我正在寻找使用实时消息替换我们公司的监控仪表板。
在我们公司,我们有一个仪表板,显示超过700台物理机的(相当详细的)状态,以及添加的元信息。它大约在1.5年前由我的一位同事在ASP.NET Web Forms(我不喜欢)中构建,以使调度员能够协调我们的技术人员应该去哪里解决问题(这些机器位于各种各样的位置)地理位置)。
不幸的是,该应用程序使用30秒的完整页面自动刷新,后面有一个大查询。它很慢,它完全重置你的视图(正如我所说,仪表板包含超过700多台机器)。我个人想改变这个。使用起来非常烦人。我们的调度员已经学会了接受这一点,但我认为他们应该得到更好的待遇。
我想在新的信息中心上显示相同的内容,但是有实时更新和"消息"登录。在我们公司,我们在MS堆栈上的工作量约为90%,因此我计划使用ASP.NET MVC,SignalR,SQL Server和Knockout。
看看这个简单的图表:
+----+ +----+ +----+ +----+ +----+ +----+ +----+
| PC | | PC | | PC | | PC | | PC | | PC | | PC | ... ...
+--+-+ +--+-+ +-+--+ +--+-+ +--+-+ +--+-+ +--+-+
| | | | | | |
| +--+ +--+ +----+ <-+ <-+ <-+
| | | |
+---v---v-----v-----v+ +-----------------------+
| | TCP/IP | |
| Monitoring Backend +---------> Data Enrichment App |
| | | |
+--------------------+ +---------+-------------+
|
+------------------------------+ +---------+
| | |
| +----------------+ | |
+-----v-----+----------> DB Proxy +-----> S Q L |
| | PUB/SUB +----------------+ | |
| Redis | | |
| | +----------------+ +---------+
+-----------+ | TO BE... |
+----------------+
这里的想法是在我的ASP.NET应用程序中将SignalR Hub订阅到Redis后端,以将事件发送到客户端。 (那是 TO BE 部分)
我们的想法是,当客户端导航到仪表板URL时,初始概述将由SQL后端中的状态数据填充。之后,通过SignalR接收事件,并通过更改Knockout属性来更新视图。
但是,如果客户端断开连接(例如,从会议室走到会议室时睡觉他的笔记本电脑),他会错过来自SignalR集线器的消息,并且他的仪表板视图不再正确!
可能的解决方案是:
在每次事件更改时通过SignalR发送每个设备的完整状态:这是不可能的,因为我必须通过线路发送大量数据。 (我猜测至少有12,000条JSON数据记录)
在检测到超时连接后强制完全刷新:我不知道如何使用SignalR实现这一点:(
......?
处理实时基于推送的数据并保证数据到达的推荐方法是什么?或者我如何处理从超时连接中恢复的问题?或者让这个实时疯狂的想法?
免责声明:我是系统工程师,而不是专业程序员。这是我的第一个实时网络应用程序。有关SignalR的其他问题通常不会处理大量此类数据。
答案 0 :(得分:5)
花钱的回答很好,但我想在SignalR的背景下解决方案2;您可以使用SignalR生命周期事件:OnConnected
,OnReconnected
和OnDisconnected
。您可以阅读更多about the events here以及如何use them in a hub here。
当客户端首次连接时(OnConnected被调用),您将完全初始化视图。如果客户端暂时失去连接(默认情况下少于30秒,请参阅relevant settings here,OnReconnected
被调用),则无需执行任何其他操作;只要标准排队机制中有足够的空间,就会传递排队的消息。
如果客户端PC进入休眠状态,最终会调用OnDisconnected
,客户端必须建立新连接。此时,最简单的实现是简单地再次加载所有数据。如果您想重用客户端已有的(过时的)数据,那么您需要
OnConnected
中读取它并知道是初始化完整视图还是仅初始化变更集使用SignalR消息进行实时更新应该没问题,但我建议使用常规的MVC / WebAPI控制器来提供初始化视图所需的完整数据集(来自OnConnected
)。
也就是说,如果您想要保证投放,您必须确认您的消息,并且可能还要实施排队机制。 SignalR默认只缓存大约1000条消息,然后开始丢弃它们。您可以增加该值,但根据您的要求构建一个可能更有意义。
答案 1 :(得分:5)
SignalR不适用于&#34;可靠消息&#34;。它专为&#34;实时通信&#34;而设计。
问题在于可靠性实际上与实时不兼容。可靠的消息传递意味着消息将至少传送一次。但是,如果数据链接已关闭,则邮件将被延迟传递。但是,实时意味着消息会立即发送,而不会在半小时后发送。
我会切换到&#34; Message Queue&#34;如果可靠性是您所需要的。你会发现他们已经足够快了#34;为了您的目的(RTC通常意味着您需要毫秒范围内的延迟,而MQ应该在第二范围内提供典型延迟)。
您的问题是,如何在SignalR上实现Message Queue。
试试RabbitMQ,我只听说过它的好东西。还有一个Javascript客户端。
答案 2 :(得分:4)
所以,我认为这个问题有点过于宽泛而且没有重点,但我还有更多话要说,而不是评论。
为了保持简单,我不会使用websocket来自己传达消息,而只是作为通知渠道让客户知道有更多数据可用。
首先,我专注于通过标准HTTP通过JSON请求有限的消息集的方法。我假设所有消息都有某种序列号或时间戳,因此已经包含带有戳n
的消息的客户端需要能够请求带有戳>n
的所有消息。我们称之为消息服务。
现在连接websocket并使用它将简单的“更多可用数据”事件传递给客户端。每次客户端收到事件时,向邮件服务发出一个新请求,要求所有邮件都带有邮票&gt;而不是客户最近的。
如果websocket断开连接,当它重新连接时,向消息服务单独发出请求以确保您处于同步状态,然后再次等待事件,如上所述。