使用SignalR的客户端实时服务器

时间:2015-03-16 08:39:16

标签: asp.net signalr real-time

让我解释一下我的申请,以便我能让读者了解我实际在做什么。

我正在将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发生变化时更好地更新客户端!

此致

2 个答案:

答案 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库?