Asp.net 使用信号器从服务器到客户端的实时通信

Asp.net 使用信号器从服务器到客户端的实时通信,asp.net,signalr,real-time,Asp.net,Signalr,Real Time,让我解释一下我的应用程序,这样我就可以让读者了解我实际上在做什么 我将MVC5与signalR一起用于web应用程序 应用程序由客户端到服务器的连接组成。另一方面,服务器还有一个连接到PLC(可编程逻辑控制器)的控制器。它是一个带有硬件IOs的简单硬件控制器 我使用信号器向plc写入,如下所示: 客户端(JS)->SignalHub->MVC控制器->PLC 我还需要服务器在PLC发生以下变化时进行广播: PLC->MVC控制器->信号灯->客户端 MVC控制器有一个事件,当plc发生变化时,会

让我解释一下我的应用程序,这样我就可以让读者了解我实际上在做什么

我将MVC5与signalR一起用于web应用程序

应用程序由客户端到服务器的连接组成。另一方面,服务器还有一个连接到PLC(可编程逻辑控制器)的控制器。它是一个带有硬件IOs的简单硬件控制器

我使用信号器向plc写入,如下所示: 客户端(JS)->SignalHub->MVC控制器->PLC

我还需要服务器在PLC发生以下变化时进行广播: PLC->MVC控制器->信号灯->客户端

MVC控制器有一个事件,当plc发生变化时,会触发该事件

问题在于,当客户端连接正常时,它确实创建了SignalHub的实例,但当它准备就绪时,集线器将被破坏,因此,如果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);
        });
    });
});
这意味着(据我所知)在document ready上创建集线器连接,并且在单击“发送”按钮时,向plc写入数据,这一点非常好

这是中心代码:

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发生变化时更新客户端


关于

首先,您有办法从集线器和MVC控制器耦合到核心逻辑

MVC控制器和集线器都有一个请求生命周期,试图让它们保存数据的时间比使用静态集合等的时间长不是好的做法

如果PLC控制器代码长时间运行,则根本不应从控制器或集线器调用,而是在集线器或控制器中将其放入队列中。让一名ASP.NET后台工作人员接手该工作。在那里处理它。然后,我会使用某种低脚印服务总线或事件聚合器发布状态。让SignalR使用您自己的库收听这些状态,或者您可以使用此库(免责声明,我是作者)

请在此处阅读ASP.NET后台工作人员


您还可以为您的后台资料创建windows服务,并使用服务总线向我的库发送信号。例如,Rabbit MQ etc

我意识到这是一个老问题,但我面临着一个非常类似的问题(甚至是与PLC交互——在我的例子中,实际上是FPGA)。我曾尝试阅读有关EventAggregatorProxy库的内容,但我很难理解它与体系结构的契合之处

相反,我在考虑详细的方法。这涉及到反转依赖关系,因此在您的情况下,PlcController将引用集线器,可能类似于:-

public class PlcController
{
    IHubContext _hubContext;

    public PlcController()
    {
        _hubContext = GlobalHost.ConnectionManager.GetHubContext<MyPlcHub>();
    }
}

您是否在解决方案中使用了EventAggregatorProxy库?

让我看看我是否理解。。。因此,您的库生成一个事件侦听器,每当后台工作人员触发事件时(例如,当我在plc上得到更改时),客户端事件也会被触发,我可以根据需要更新客户端,对吗?换句话说,我只需要一个后台工作人员就可以工作,而不需要使用MVC?是的,您需要立即开始工作,可以通过Hub或WebAPI控制器或MVC控制器(尽管WebAPI已经用REST替代了MVC控制器)。之后,您的后台工作人员将在您的总线上发布状态,我的库将无缝地将它们转发给所有或相关的客户端(它有一个用于约束的内置API)。谢谢,我将尽量充分利用您的库,并让您知道。唯一的问题是从何处启动worker,以便我始终处于相同的作用域中和
RouteTable.Routes.MapEventProxy()说我缺少一条指令你有关于如何使用你的库的解决方案吗?我的意思是比文档更详细。。。抱歉,我不熟悉这种类型的编程RouteTable.Routes.MapEventProxy();是SignalR 1.x代码,您应该使用第一个语法。app.MapEventProxy();
_hubContext.Clients.All.broadcast(s);