让我解释一下我的申请,以便我能让读者了解我实际在做什么。
我正在将MVC5与signalR用于Web应用程序。
该应用程序包含客户端到服务器的连接。另一方面,服务器还有一个连接到PLC(可编程逻辑控制器)的控制器,它是一个带有硬件IO的简单硬件控制器。
我正在使用SignalR写入plc,如下所示: 客户端(JS) - > SignalRHub - > MVC控制器 - > PLC
我还需要服务器在PLC发生变化时进行广播,如下所示: PLC - > MVC控制器 - > SignalRHub - >客户端。
MVC控制器有一个事件,当plc发生变化时,它会被触发。
问题在于,当客户端连接正常时,它会创建SignalRHub的实例,但是当它准备就绪时,Hub会被破坏,因此如果PLC发生了变化,它就会完全丢失,无法推送到客户端。
客户代码是:
$(document).ready(function () {
var chat = $.connection.chatHub;
console.log(chat);
chat.client.writeMessage = function (msg) {
console.log(msg);
}
var i = $.connection.hub.start().then(function (event) {
$('#send').click(function () {
console.log("clicked");
chat.server.plcWrite(true);
});
});
});
这意味着(据我所知)文档就绪创建了集线器连接,并且当单击按钮#send时写入plc,它完全正常。
这是Hub代码:
Controllers.PlcController plc = new Controllers.PlcController();
//public void bMessage()
//{
// Clients.All.writeMessage(x);
// }
public void plcWrite(bool write)
{
plc.plcWritebool(write);
plc._broadcast += plc__broadcast;
}
void plc__broadcast(object sender, EventArgs e)
{
bool s = plc.plcRead();
Clients.All.broadcast(s);
}
我正在阅读的问题是,当客户端点击按钮时,它始终会创建一个新的控制器,并在准备就绪时丢失。
有没有人有任何想法,以便保持集线器始终相同并始终与我的控制器保持连接?如果您需要更多信息,请希望解释清楚,请不要犹豫!
编辑:我知道我可以使用来自客户端的轮询频率,但它会创建大量的流量,而且我必须访问plc,每次民意调查都不灵活。当plc发生变化时更好地更新客户端!
此致
答案 0 :(得分:0)
首先,您可以通过集线器和MVC控制器与Core逻辑进行大量耦合。
MVC控制器和HUB都有一个请求生命周期,试图让它们保持数据的时间比使用静态集合等更长,这不是一个好习惯。
如果PLC控制器代码长时间运行,则根本不应从控制器或HUB调用,而是在HUB或控制器中将其置于队列中。让ASP.NET后台工作者选择该作业。在那里处理它。然后我会使用某种低脚印服务总线或事件聚合器发布状态。让SignalR使用您自己的库来监听这些状态,或者如果您愿意,可以使用此库(免责声明,我是作者)。
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki
在此处阅读ASP.NET后台工作者 http://blogs.msdn.com/b/webdev/archive/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-long-background-process-in-asp-net.aspx
您还可以为您的背景资料创建一个Windows服务,并使用服务总线发信号通知我的图书馆。例如Rabbit MQ等
答案 1 :(得分:0)
我意识到这是一个老问题,但我面临着一个非常类似的问题(甚至是与PLC交互 - 在我的情况下实际上是一个FPGA)。我已经尝试过阅读有关EventAggregatorProxy库的内容,但我很难理解它在适合架构的地方!
我正在考虑详细的方法here。这涉及逆转依赖关系,因此在您的情况下,PlcController将引用Hub,可能是这样的: -
public class PlcController
{
IHubContext _hubContext;
public PlcController()
{
_hubContext = GlobalHost.ConnectionManager.GetHubContext<MyPlcHub>();
}
}
阅读PLC后,您将使用以下语法广播结果:
_hubContext.Clients.All.broadcast(s);
您最终是否在解决方案中使用了EventAggregatorProxy库?