六、服务端实现
6.1 概述
本章所说的服务端,是“仪器-工控机-服务器-客户端”架构中的服务端,并不实现采集功能(采集功能已在前面的章节讲述)。我们要实现的服务端是有高实时性的,当数据发生改变时,迅速地推送给客户端。同时,客户端上的反控操作,能快速地反映到仪器上。
MQTT是实现此类服务端较好的技术选择。以“设备名.因子名”为主题,当采集到变化的数据时,发布相应主题。客户端根据当前显示需要,订阅相关的主题。同时,工控机订阅一个专门的反控主题,任何客户端的反控操作都发布该主题。
6.2 服务端技术实现
使用MQTTnet开发MQTT服务器,同时支持TCP模式和WebSocket模式。为了支持WebSocket,必须建立一个ASP.NET Core项目,然后修改Program.cs为:
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
private static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(o =>
{
o.ListenAnyIP(9022, l => l.UseMqtt());//TCP
o.ListenAnyIP(9021);//WebSocket
})
.UseStartup<Startup>()
.Build();
修改Startup.cs为:
public void ConfigureServices(IServiceCollection services)
{
services
.AddHostedMqttServer(mqttServer => mqttServer.WithoutDefaultEndpoint())
.AddMqttConnectionHandler()
.AddConnections();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapMqtt("/mqtt");
});
app.UseMqttServer(server =>
{
//处理MQTT消息
});
}
对MQTT服务器来说,工控机和网页客户端都是客户端,如下图所示:
由于存在反控,工控机分别订阅了不同的反控主题。而对客户端来说,它是一个整体的展现,并不太关心什么数据来自哪个工控机。所以,在反控时,服务端需要对反控命令进行分发。
6.3 客户端技术实现
客户端使用mqtt.js实现功能,通过WebSocket的方式连接服务端。所有因子的主题为一个保留主题,基本客户端刚连接就可以收到最新的因子列表。它再通过这个列表订阅相关的因子主题,得到因子的最新数值。
下面,我们模拟了一个从仪器到工控机,到服务端,再到客户端的场景。
8台虚拟Modbus设备,约700个因子:
模拟两台工控机,每台采集4台仪器:
模拟MQTT服务端:
模拟Web客户端: