基于B/S架构的管理系统软件开发
2019-03-05,,,
,, ,
(中国石油大学(北京)地球物理与信息工程学院,北京 102249)
0 引言
目前,4G网络已经全面覆盖,移动互联网也处于高速发展中,高科技信息化技术已经深入到生活的各个方面,随之给我们的工作生活带来了更加便捷、灵活的工作方式。警用摩托车管理系统让用户通过浏览器来直观地获取车辆的地理位置以及基本信息数据,并且能够直接播放车辆的行车记录视频。
警用摩托车管理系统由安装于摩托车上的智能化终端设备、服务器、MySQL数据库组成。终端采集上传摩托车数据、视频信息;服务器接收终端上传的数据,并将数据存入数据库,并接受前端发起的请求,根据请求调用数据库提取相应信息,打包处理后通过响应的方式交给前端。
1 整体设计
系统整体设计如图1所示。系统由安装于摩托车上的智能化终端设备、服务器、MySQL数据库组成。智能化终端设备完成对摩托车位置、车速故障信息等数据的采集、上传。服务器将终端上传的数据解码存入数据库;接收来自前端的请求,包括数据请求和视频直播请求,收到请求后会根据数据请求的具体内容,从数据库检索数据,并将数据转换成JSON格式给前端应答,视频请求则不作处理,以广播的形式直接下发给终端。前端接收用户请求向服务器提取数据,并将数据进行包装,直观地展现给用户。
图1 系统整体设计框图
2 服务器
服务器分为两部分:一部分为TCP服务器,与硬件终端设备通信,接收、解析、保存数据;另一部分为HTTP服务器,与前端通信,提取、打包、发送数据。
2.1 TCP服务器
由于摩托车终端数量较多且数据发送频繁,故选用NETTY框架搭建TCP服务器。
Netty是一个基于非阻塞IO的快速开发高性能、高可靠性的网络服务器-客户端架构。Netty封装了Java NIO那些复杂的底层细节,提供简单好用的抽象概念来编程,广泛应用于客户端与服务器长连接、高并发的场景。最近几年,Netty 在计算机互联网行业迅速流行开来,已经成为 Java 通信编程架构的第一选择。
对于NETTY服务器端而言,属于被动接收请求,服务端bind端口采用随机的方式,以避免单台服务器多端口之间的冲突。通过ServerBootstrap创建服务器端通讯连接。此外,采用ChannelGroup类,既可以自动将被关闭的Channel从ChannelGroup中删除,还可以统一关闭ChannelGroup中的所有通道。
部分代码如下:
public void bind() {
EventLoopGroup bossGroup = new NioEventLoopGroup();//用于接收客户端连接
EventLoopGroup workGroup = new NioEventLoopGroup(); //用于进行网络读写通信
try {ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workGroup);//绑定两个线程
b.channel(NioServerSocketChannel.class);
b.option(ChannelOption.SO_BACKLOG, 1024);
b.childHandler(new ChildChannelHandler());
// 绑定端口
ChannelFuture f = b.bind(53606).sync();
// 等待服务端监听端口关闭
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally { //退出
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
服务端在初始化的时候,由于我们需要对接收的数据进行处理,于是在通道中添加我们自己接收数据实现的方法类,以及5分钟判断客户端的在线离线状态。并且对于粘包拆包问题的处理上,采用的了基于换行符的处理方式。
部分代码如下:
protected void initChannel(SocketChannel ch) throws Exception {
System.out.println("IP:" +
ch.localAddress().getHostName());
System.out.println("Port:" +
ch.localAddress().getPort());
// 5分钟判断在线离线
ch.pipeline().addLast(new IdleStateHandler(300,0,0));
// 半包处理[基于换行符]
ch.pipeline().addLast(new
LineBasedFrameDecoder(1024));
// 字符串编码
ch.pipeline().addLast(new StringDecoder());
// 字符串解码
ch.pipeline().addLast(new StringEncoder());
// 在管道中添加我们自己的接收数据实现方法
ch.pipeline().addLast(new MyServerHanlder());
}
在保证服务器能够接收到所有终端的数据并且不丢失的前提下,还要根据终端用户ID号,对数据包是否有效进行判断。如果ID与数据库中注册ID符合则服务器接收数据并存入数据库,如不符合,则拒绝接收。判断用户ID流程图如图2所示。
图2 判断ID流程图
对于终端的在线离线状态,将借助NETTY提供的IdleStateHandler类,如下:
public IdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {this((long)readerIdleTimeSeconds, (long)writerIdleTimeSeconds, (long)allIdleTimeSeconds, TimeUnit.SECONDS);}
即实现心跳机制的类,来处理客户端的连接状态。其中:readerIdleTimeSeconds为读超时;
writerIdleTimeSeconds为写超时;
allIdleTimeSeconds为所有超时。
而根据实际情况以及产品需求,在服务器初始化时,通道中添加的方法为:
ch.pipeline()addLast(new IdleStateHandler(300,0,0));即读超时设置为5分钟。系统认为5分钟内未发送数据,服务器将断开连接,并将状态记录存储到数据库中,同时不再刷新该终端的实时状态。判断在线、离线状态流程图如图3所示。
图3 判断状态流程图
2.2 HTTP服务器
HTTP用于接受前端的请求,根据请求调用数据库提取相应信息,打包处理后通过响应的方式交给前端,数据交换格式为JSON,一种轻量级的数据交换格式。
HTTP服务器接收前端的请求,并对请求进行解析,解析方式为字符串匹配,根据解析出来的条件对数据库执行检索。完成对数据库的操作后将数据打包成JSON格式,响应给前端。
JSON作为更轻、更便捷的Web service客户端格式,目前广泛应用于编程开发中。相较于XML格式,它更加便于读取,JSON中的分隔符限于单引号、小括号、大括号等,而JavaScript引擎对数据结构的内部表示正好与这些符号相同,以此简化了数据的访问。此外,它的另一个优点是其非亢长性。传统的XML标记会增加数据交换时间,必须包括打开和关闭标记,才能满足标记的依从性,而在JSON中所有这些要求只需要通过括号即可满足。所有JSON的线上传输效率更高。
部分请求响应JSON格式如下:
if(包含all_motor)//实时位置
{
"Motor":
[
{
"ID":"4661",
"data":
{
"longitude":"XXXX",
"latitude":"XXXX",
……}
},
{
"ID":"4662",
"data":
{ ……}
},…… ]
}
if(包含real)//实时轨迹
{
截取命令字段中的ID,通过ID在数据库moto_real_time表中查找 最新更新时间,根据这个时间以及ID,在moto_historic表中检索 当天该ID的所有数据,数据格式同上。
}
if(包含video)//视频开关
{
直接将video字段后的命令广播发送给终端。
数据格式:ID=XXXX/state=X/channel=X/
}
3 MySQL数据库
MySQL数据库体积小、速度快,多用户、多线程并且能够处理大量数据[9],主要以小型应用为主,主要设计目标是实现数据操作速度优化且不影响SQL支持性能。应用程序通过JDBC API接口引入JDBC驱动对数据完成操作,部分程序如下:
public static void Table_Create() {
Class.forName("com.mysql.jdbc.Driver");
try(
//使用DriverManager获取数据库连接,
//其中返回的Connection就代表了Java程序和数据库的连接
//不同数据库的URL写法需要查驱动文档知道,用户名、密码由DBA分配
Connection conn = DriverManager.getConnection(
"jdbc:mysql://127.0.0.1:3306/mysql"
, "root", "123456");
//使用Connection来创建一个Statment对象
Statement stmt = conn.createStatement()){
stmt.executeUpdate("create table if not exists motor_register"
//创建表格字段名
+"(XXX int not null primary key,"
+" XXX varchar(255),"
……
+" XXX varchar(255));" );
}
}
根据数据量分布以及客户需求,设计三个车辆信息表,分别为摩托车登记表、摩托车实时状态表和摩托车历史数据表。登记表和实时状态表中都设置以clientID为主键且非空,由于在此两表中clientID不可重复存储,此外实时状态表中的uploadDate字段是联合主键,为确保实时表格的准确性。三个表格之间的关系如图4所示。
图4 数据库E-R图
FieldTypeNullKeyDefaultclientIDInt(11)NOPRINULLmotobrandvarchar(255)YESNULLmotolicensevarchar(255)NONULLpoliceIDvarchar(255)NONULLmotostatusvarchar(255)YESNULL
摩托车登记表用于记录摩托车序列号、摩托车品牌、摩托车车牌、归属警员号、摩托车状态等基础信息,每辆摩托车拥有唯一序列号,只有经注册将信息录入登记表,服务器才会接收ID号符合的数据包存入数据库,进而调取车辆状态信息。数据名称以及数据类型属性如表1所示。
摩托车当前状态表存储摩托车最新状态,数据包括用户ID、用户名称、状态更新时间、速度、里程、当天里程在线离线状态等,一个ID 对应一条记录。当终端被判断离线后,状态变为“1”,再将数据异步存入至历史表。历史状态表存储所有车辆的所有信息,方便前端调取查阅车辆历史轨迹,也可以检索某时间段某辆车的详细数据。当前状态表如表2所示。当前状态表如表3所示。
表2 摩托车当前状态表
表3 摩托车历史状态表
4 视频直播
视频直播是通过基于Android操作系统的终端设备,搭建基于RTMP传输协议的流媒服务器,最终在前端流媒体播放器上实现。摄像头开关由前端控制,媒体流通过RTMP协议进行传输和播放。
RTMP(Real Time Messaging Protocol),即实时消息传送协议,是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用和分包问题。并且随着VR技术的发展和视频直播等领域的发展,RTMP协议逐渐热门起来,在高速发展的流媒体市场中得到广泛的应用[10]。
视频直播流程分为以下几步:(1)采集;(2)处理;(3)编码和封装;(4)推流到服务器;(5)服务器流分发;(6)播放器流播放。
当前端发送开启直播命令时,终端摄像头启动采集实时音视频,并编码成H.264码流,视频服务器启动建立与终端的链接,然后接收码流并推流至前端播放以及进行实时存储,以MP4格式保存至本地。
终端视频格式不是可以直接观看的MP4格式,而是封装为H.264,且每个视频时长10秒。由于前端HTML5不支持此类视频的播放,需要视频服务器对视频进行实时的格式转换处理,服务器中调用了FFmpeg应用程序,将H264转换为MP4,处理后的视频放到指定路径,供前端调用。
5 实现效果
警用摩托车管理系统前端主要包括系统登录界面、车辆注册界面、实时监控界面、信息检索界面、车辆信息界面五个部分。
5.1 系统登录及注册
警用摩托车登录系统界面部分用于保障系统安全,设置使用权限,用户只需要输入提前设置的用户名、密码便能够成功登录该管理系统,然后进入主界面。
警用摩托车系统注册界面,用于录入摩托车基本信息,包括摩托车序列号、摩托车品牌、摩托车车牌、警员号、摩托车状态信息等,限制摩托车序列号位数字,各栏均不为空,否则会提示错误,注册不成功。注册成功后,会将信息写入数据库motor_register表,只有在motor_register表中录入信息的车辆,在界面中才可以查询其信息。
5.2 实时监控界面
实时监控界面如图5所示,主要功能为在地图上直观显示所有车辆位置,同时在最标点标签上显示车辆ID以及电量信息等简要信息。
图5 实时监控界面图
5.3 信息检索界面
信息检索界面如图6所示,可通过输入ID号查找某辆车信息,显示实时轨迹并播放实时视频。视频窗口上方显示该车辆的状态,包括实时速度、里程等。具体操作是在ID输入框内输入车辆ID,单击ID输入框后的确定按钮,跳转查看该车辆的信息,若输入ID不存在,则会弹框提示。选择好起止时间后,单击时间选择框后的确定按钮,可以查看该车辆在某个时间段的轨迹以及录像。
图6 信息检索界面图
5.4 车辆信息界面
车辆信息界面默认显示所有车辆最新信息如图7所示,信息包括车辆ID、摩托车品牌、经纬度、里程、故障信息以及更新时间等。可根据表头某一项信息对表中元素进行排序。表格右上方Search框可输入车辆ID,检索某一车辆的所有信息,点击表格标题栏可切换显示所有车辆当天所有信息。
图7 车辆信息界面图
6 结束语
在4G网络全面覆盖和互联网产业的迅速发展的背景下,使人们的工作方式越来越多样化,利用网络的便捷设计的警用摩托车管理系统,方便了单位实现内部车辆合理调配以及有效排查车辆故障获取车辆基本信息,可以极大地提高公安人员的执法效率。本文设计的软件主要是基于B/S架构,实现了警用摩托车基本数据采集、数据存储管理和行车记录视频直播等功能。
本文完成的主要工作有以下两大部分内容,即后台服务器和前端浏览器。
6.1 后台服务器
系统服务器车辆基本信息通讯部分主要由NETTY框架、HTTP协议和MySQL数据库搭建而成,行车记录视频由RTMP搭建而成。实现了接收终端发送的protobuf数据并解码存入已设计好的数据库,数据库的设计满足每次访问数据库的效率最优。HTTP协议用于接收前端请求数据并作出响应,根据请求提取数据库相应信息,数据将以JSON格式发送给前端[8]。行车记录视频通过搭建基于RTMP传输协议的服务器实现视频流推送到RTMP服务器,再将视频发送给前端进行直播。此外,终端录制的视频可以通过服务器转化为MP4格式保存至本地。
6.2 前端页面
主要应用HTML、CSS和JavaScript技术设计网页,可实现在地图上展示车辆位置以及车辆基本信息,可针对某辆车某时间段行车轨迹进行查询和观看行车记录视频。
本文运用了目前最流行的框架和直播技术,设计的警用摩托车管理系统软件,最终通过测试成功实现以上所介绍的功能。为办公人员提供了便捷的管理服务,大大优化了工作效率。