APP下载

Nodejs平台下远程视频和信号监控系统的融合

2019-02-20李丹清韩利峰李嘉曾吴丽梅张立园陈永忠

仪器仪表用户 2019年3期
关键词:调用客户端服务器

李丹清,韩利峰,李嘉曾,吴丽梅,张立园,陈永忠

(1.上海交通大学 软件工程学院,上海 200240;2.中国科学院上海应用物理研究所 系统工程部,上海 201800)

0 引言

视频监控系统经历了由模拟到数字的转变,目前发展到第三代,通过利用多媒体压缩算法,网络通讯以及人工智能,更加趋向于网络化和智能化[1]。

伴随着网络通讯技术的进步,大型SCADA(Supervisory Control And Data Acquisition)系统和视频监控系统的平台融合、信号联动[2-4]逐渐成为可能。

在电力行业和轨道交通行业初步解决了系统间人为切换,但没有互动的情况[5,6]。解决方案是SCADA系统的操作处理,通过事件的方式触发执行机构动作,同时通过联动服务器弹出视频画面,观察事件处理状况。这种简单的互动不具有视频监控系统纵深层次的优化和横向平台扩展的设计理念,况且越来越多的需求体现在视频、环境、生产、运行等全面信息的深度融合。

解决平台间信息的深度融合需要解决以下问题:统一的平台下能同时支持SCADA通讯协议和视频传输通讯协议;拥有事件处理机制,能实现两系统之间的事件传递;拥有可靠的数据传输通道,解决客户端信号数据和视频数据的传输;拥有前端的数据渲染能力,能同时渲染实时变量数据和视频流数据;具有深度融合所需要的数据处理,图像处理、智能算法能力。

Nodejs平台具有以上描述的系统集成和深度融合的能力。首先,它是一个让JavaScript运行在服务端的开发平台,采用Google-V8引擎作为编译器,使得JavaScript的执行速度远超Ruby、Python等脚本语言;另外,Nodejs具有开发实时监控系统的能力,它采用事件驱动、异步编程、非阻塞模式的IO处理工作机制,为其带来在相对低系统资源耗用下的高性能与出众的负载能力,非常适合用作依赖各种IO资源的中间层服务,可完美解决数据IO密集型、分布式部署环境下的实时应用系统[7-9]。

其次,Nodejs具有强大软件包管理工具npm,它的在线代码库包含功能齐全的代码模块,如项目中使用的Web网站架设模块Express,WebSocket通讯模块socket.io,EPICS libCA接口模块,node-epics、OpenCV算法模块等都可以通过npm管理器安装[10,11]。

再者,Nodejs可以通过FFI(Foreign Function Interface)调用本地C/C++链接库,把视频采集、解码、算法处理等集成到平台之下[12,13]。

本系统的开发就是基于Nodejs平台,把Web网站服务,EPICS监控系统,视频采集融合在一起。结合中科院TMSR(Thermal Molten Salt Reactor)核能项目,完成一套综合实验室安全监控系统的开发。该系统实现了对项目内的放射化学、熔盐化学、高温材料、同步辐照、电解制氢、集热传热等实验室内环境、设备安全、火警、视频等信息的一站式监控[14]。

1 系统结构

如图1所示,本系统中使用Express框架建立Web网站。Express是由Nodejs提供的一款精简、灵活的Web开发框架。它提供了路由,模块支持,模板引擎,以及中间件等相关功能[15]。

系统服务器通过两种方式与客户端进行通信:一种是HTTP协议。客户端发送Get请求或者Post请求,HTTP服务器在接受到请求时,通过路由机制以及中间件处理,来传送页面静态数据;另一种是WebSocket协议。这种协议通过一次握手,建立浏览器和服务器之间一条可复用的通道,可以让服务器主动并且不断推送信息,来传送实时性动态数据[16,17]。

图1 实验室监控系统软件架构Fig.1 Laboratory monitoring system software architecture

系统通过socket.io建立客户端与服务端的TCP连接对象,通过IP地址和端口号,规定目标服务器。服务器在接受到来自客户端的请求之后就会建立相应的长连接来发送实时数据。

系统服务器端与第三方实时系统通信来获取实时的数据,其中包括火灾警报系统,EPICS实时信号监控系统和视频监控系统。与火灾警报系统的通信依赖于Modbus接口,与EPICS实时信号监控系统的通信依赖于libCA接口,而与视频监控系统的通信依赖于视频软件供应商提供的SDK[18]。

node-ffi是一个Nodejs的第三方功能模块,本质上是一个已经将Google-V8封装好的专门用来调用动态库/静态库的功能插件。本系统所使用的node-modbus和node-epics模块的内部机制就是利用node-ffi对相应接口的封装,使其能在Nodejs环境下运行。但是本系统的视频软件的SDK并没有可以在Nodejs环境下运行的API,所以必须手动利用node-ffi对相应的SDK进行封装并加以利用。

系统在客户端通过JQuery、Angular、Echart、DataTable等基于JavaScript的框架进行数据可视化,通过Canvas来进行视频图像的显示。

图2 实时预览流程图Fig.2 Real-time preview flowchart

图3 实时视频监测实现流程图Fig.3 Real-time video monitoring implementation flowchart

2 系统实现

2.1 SDK视频接口封装

本系统的视频软件SDK提供了视频图像采集和视频播放控制的软件开发包。它们提供了可以供C/C++、C#和Java调用的API,但并没有提供JavaScript调用的API。因此,需要通过node-ffi封装相应的API以供JavaScript调用。封装好的API就可以在Nodejs平台上直接调用并且进行功能模块的开发。

2.1.1 程序实现流程

SDK提供了设备网络SDK和播放库SDK。设备网络SDK主要提供了实时码流预览、录像文件下载、云台控制、日志管理、格式化硬盘、参数配置等相关功能的开发模块。播放库SDK主要用于播放控制的相关功能的开发。

如图2所示,本系统主要起到实时监测的功能,故调用SDK中的实时预览功能开发流程。根据实时预览流程完成程序实现流程,如图3所示。

首先,需要通过NET_DVR_Init函数完成对设备的初始化,包括网络初始化和内存预分配等。之后设置设备连接时间(NET_DVR_SetConnectTime)和设置设备重连次数与时间(DVR_SetReconnect)。

运行注册函数(NET_DVR_Login_V30)需要传入设备IP、端口号、用户名、密码等参数以供完成相应的设备注册,从而获取相应设备的使用权限。

NET_DVR_SetExceptionCallBack_V30函数用来捕捉异常信号。此函数基于事件驱动,如果产生异常信号则触发其回调函数fExceptionCallBack来进一步处理异常信息。

NET_DVR_RealPlay_V40接口函数用于启动预览,此函数通过传入注册设备时返回的句柄来获取需要播放的视频数据的内存空间,也是基于事件驱动,每当产生视频流数据时,触发其内部回调函数fRealDataCallBack。

为了便于视频图像的显示与传送,要求所有的视频帧图像数据以JPEG格式进行编码,同时JPEG格式数据必须存于内存中,SDK提供了相应的内存抓图接口函数PlayM4_GetJPEG。

为了调用此接口函数,需调用播放库接口函数PlayM4_SetDecCallBack,此函数将图像帧数据转交给内部回调函数DecCBFUN来处理,在DecCBFUN内部调用PlayM4_GetJPEG将视频图像数据编码成JPEG格式。

2.1.2 数据类型封装

Nodejs是基于JavaScript运行的平台。JavaScript的变量基于弱类型,变量在声明时并不需要说明其类型。它的变量类型只有在初始化时,才得以确定。同理,它的函数的返回类型以及参数类型在函数声明时不需要确定,只有调用函数,传入实参时,类型才能够确定。而C/C++的变量是基于强类型,也就是变量在声明时就必须指明具体的类型。对于函数声明也是如此,函数的返回类型以及参数类型在函数声明时也必须确定。因此,通过JavaScript调用基于C/C++编写的接口函数时,首先需要解决的是变量类型的封装与预声明的问题。

为了完成变量类型的封装,首先必须引入3个第三方功能模块,分别是ref、ref-array与ref-struct。

安装完毕后,3个模块的文件包置入Express框架的modules文件夹下,通过require函数引入即可使用。其中,ref模块用于变量基本类型与指针类型的封装,ref-array模块用于数组类型的数据封装与预声明,而ref-struct模块则用于结构体的类型封装与预声明。

动态库调用:

通过ref、ref-array与ref-struct模块完成数据类型的封装与预声明后,就可以调用node-ffi模块封装相应的动态库的接口函数。

通用格式如下:

var NewFun=new ffi.Library(“动态库路径”,{

‘调用函数名1’:[‘函数返回类型1’,[‘形参类型1’,‘形参类型2’,‘形参类型3’…]})

封装动态库接口函数需要输入以下参数:

1)动态库路径:SDK动态库所在路径。

2)调用函数名:为SDK动态库对应API的函数名。

3)函数返回类型:通过数据封装后,预声明的数据类型,用于定义函数返回类型。

4)形参类型:通过数据封装后,预声明的数据类型,用于定义形参类型。

封装后的动态库利用之前声明的JavaScript实例(NewFun)进行调用。

通过这种通用格式,封装实时预览开发模块中需要的API,通过这些API完成实时预览的功能开发,将功能模块封装成JavaScript库,对外生成可以直接调用的API(getVideo),通过向此函数中传入设备IP、端口号、用户名以及密码,直接通过它的回调函数输出JPEG格式的视频图像数据并加以处理。

2.2 TCP/WebSocket建立

如图4所示,系统使用基于Nodejs的第三方功能模块socket.io建立TCP/WebSocket连接。连接需要从客户端和服务器两方面进行建立,在两者之间建立一个可以双向传送数据的通道,该通道在一次连接之后便可以复用,完成数据实时推送,事件的监听或者事件的发射。

图4 WebSocket连接建立流程Fig.4 WebSocket Connection establishment process

在服务器方面,先实例化socket.io,生成对象io。利用io提供的API(io.listen)监听HTTP服务器,等待客户端的连接信号。在连接完成之后,根据客户端的Get请求,调用JavaScript库的API(getVideo),完成相应设备的视频图像数据的获取并编码(成为JPEG格式的图像)。然后通过io对象的API(emit)发射图像数据,将图像数据发送到客户端。最后在接收客户端发来的停止信号后,调用io的监听函数进行事件获取和视频推送停止处理。

在客户端方面,通过在脚本中引入socket.io.js来初始化WebSocket协议,之后创建Connect类用于连接服务器,并且在实例化Connect对象时通过传入IP和端口号的方式确定需要连接的目标服务器,在Connect类内部创建监听函数用于监听来自于服务器的连接成功事件和视频图像数据传送成功事件,在播放确认(submit)后,发送基于HTTP的Get请求至服务器,HTTP服务器在接收到Get请求后,调用相应的库函数,并利用WebSocket协议发送视频图像数据到客户端,客户端接收到视频图像数据后,调用Socket.on(‘Canvas’,fun(data))所定义的事件回调函数,对收到的视频图像数据进行处理和显示。如希望停止播放,发送停止信号至服务器,对应的调用Socket.on(‘disconnect’,fun())来做停止播放后的后续处理。

2.3 视频数据显示

图5 信号联动交互图Fig.5 Signal linkage interaction diagram

Canvas是HTML5的新引进的一个标签,主要是提供了画布的功能,开发者可以使用Canvas以及其提供的API,在画布上绘制想要绘制的图像,也可以将BMP图像以及JPEG图像,直接在Canvas画布上直接显示。当然Canvas本身没有画图的属性,它是通过获取绘制上下文(Rendering Context),并利用这种绘制上下文来进行绘图或图像显示。Canvas的绘制上下文,现今有两种:Canvas2D所提供的API和WebGL所提供的API,前者往往用于绘制2D图像和2D图片显示,后者主要应用于绘制3D图形[19]。考虑到实时视频监控系统本身特点,这里选用Canvas2D来显示图像。

在服务器接收到来自摄像头的视频图像数据后,为了方便Nodejs进行调用和处理,系统利用Nodejs所提供缓冲区技术(buffer)来接收并封装视频图像数据。通过buffer提供的编码功能将视频图像数据转化成base64格式的字符串,以方便客户端显示和数据推送。

在客户端接收到base64格式的JPEG图像数据后,利用Canvas提供的API进行图像实时显示。

基本实现流程如下:

1)通过标签的ID获取canvas对象

var canvas=document.getElementById(‘videostream’)

2)获取Canvas2D的绘制上下文

var context=canvas.getContext(‘2d’)

3)创建图像对象来接收来自服务端的视频数据

var imageObj=new Image()

4)通过图像源的方式,将base64编码的JPEG格式的图像数据嵌入到图像对象中

imageObj.src=“data:image/jpeg;base64,”+data

5)将图像数据通过Canvas2D的绘制上下文进行显示

context.drawImage(imageobj,0,0,context.width,context.height)

图6 TMSR视频监测系统页面图Fig.6 TMSR Video monitoring system page diagram

2.4 信号联动与系统实现

如图5所示,本系统基于Nodejs集成火灾警报系统,EPICS信号监控系统以及视频监控系统,在客户端登陆后,系统需获取火灾警报信号,EPICS实时数据以及实时视频图像数据。通过HTML5,CSS等渲染工具,以网页的形式将数据显示以供给用户查看。在火灾警报系统或EPICS实时系统发出异常信号时,系统通过Nodejs服务器将信号加工之后发送给客户端,客户端浏览器弹出新的浏览界面,之后新的浏览界面发送Get信号给Nodejs服务器,在服务器获取到发送出异常信号的实验室视频数据后,通过WebSocket协议将实时视频图像数据发送给客户端。客户端新界面接收到图像数据后,通过Canvas显示实时视频,如图6所示。

3 小结

本文着重阐述Nodejs平台下两系统融合的方法,网络摄像头通讯接口的封装,基于WebSokcet技术的实时视频数据传输,以及基于Canvas前端视频流的显示等。在TMSR研究堆的实验室安全监控系统中的应用,为核能项目的实验开展提供了安全保障。

猜你喜欢

调用客户端服务器
核电项目物项调用管理的应用研究
通信控制服务器(CCS)维护终端的设计与实现
如何看待传统媒体新闻客户端的“断舍离”?
PowerTCP Server Tool
县级台在突发事件报道中如何应用手机客户端
孵化垂直频道:新闻客户端新策略
大枢纽 云平台 客户端——中央人民广播电台的探索之路
得形忘意的服务器标准
基于系统调用的恶意软件检测技术研究
计算机网络安全服务器入侵与防御