共享单车服务器及客户端设计与实现
2018-03-03王风雷秦会斌崔佳冬
王风雷+秦会斌+崔佳冬
摘 要:为了改善共享单车机械锁密码不安全、电子锁成本高的不足,设计并实现了基于蓝牙控制的共享单车系统。单车车锁采用蓝牙与Android客户端通信,客户端App请求云服务器获得对车锁的开关控制,将用户信息、单车信息上传至云服务器,云服务器将信息持久化到数据库中。针对手机的高并发访问量,云服务器搭载Nginx,实现负载均衡和反向代理。测试结果表明,该共享单车系统成本低、安全性高,通过该系统,用户可以请求云服务器实现对单车车锁的控制。
关键词:共享单车;云服务器;Android;蓝牙
中图分类号:TP311 文献标识码:A 文章编号:2095-1302(2018)02-00-04
0 引 言
共享单车是中国互联网创新的应用实践,解决了“最后一公里”的问题,缓解了交通拥堵,真正实现了绿色出行,利国利民[1]。目前,共享单车机械车锁的密码由用户通过App获取,密码不可改变,安全性低;电子车锁需要连接云服务器,安全性高,但是硬件设计复杂、成本较高、耗电量高。针对以上问题,本文提出了基于蓝牙控制的共享单车系统设计方案。通过Android手机匹配单车蓝牙车锁,请求云服务器获取“钥匙”,实现对车锁的开关控制。同时,云服务器将用户和单车的信息持久化到数据库中。
1 系统总体设计
系统由Android客户端、网页后台管理中心、云服务器和蓝牙单车车锁组成。系统框架如图1所示。
云服务器是整个系统的调控计算平台[2],为管理人员与手机App提供服务,响应用户与管理人员的操作。手机App发送HTTP请求到云服务器,解析云服务器返回的JSON数据,下发蓝牙控制信息,经车锁蓝牙MCU处理后,最终达到控制车锁开闭的功能。蓝牙车锁也可通过串口向蓝牙模块输出蓝牙信息,手机App响应蓝牙信息,最终实现手机App与硬件控制部分的双向通信。
用户在注册登录成功后,进入用车界面;打开手机蓝牙,匹配车锁蓝牙,App后台将用户信息和车锁信息上传到云端服务器;用户点击开始用车,云服务器接收到请求后,记录用户信息和车锁信息,并返回“钥匙”给App,通过蓝牙与车锁通信打开车锁。当车锁关闭后,蓝牙将已锁状态发送给App,App界面结束用车,若中途断开蓝牙,则结束用车后用车界面无法进行操作。手机端用车的业务流程如图2所示。
2 云服务器的设计与实现
2.1 云服务器架构
云服务器架构图如图3所示。
本文采用阿里云作为云计算中心,提供简单高效、处理能力可弹性伸缩的计算服务。阿里云上搭载Nginx、Tomcat、Redis和MySQL,Nginx 作为反向代理,将 App 端或者浏览器端的请求根据权重分配给两台Tomcat,Redis作为两台Tomcat的共享session数据服务器,缓存已验证的用户信息。
Tomcat1的IP地址为106.15.90.190,Tomcat2的IP地址为106.14.9.111,在106.15.90.190的云服务器上搭载Nginx,配置Nginx,具体的配置如下[3]:
worker_processes 2;
events {
worker_connections 1024;}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
//配置被代理的服务器
upstream live_node {
server 106.15.90.190:8080;
server 106.14.9.111:8080;}
server {
//配置访问域名及监听80端口
listen 80;
server_name 106.15.90.190;
//指定被代理目标
location / {
proxy_pass http://live_node;}
//配置错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;}
}
}
当有请求时,通过Nginx将请求进行转发[4],保证一个入口將所有请求转发到Tomcat1或Tomcat2,同时减轻这两台Tomcat的负载压力。将Tomcat1和Tomcat2的session缓存到Redis中[5],确保访问的是同一个session,配置Tomcat conf目录下的context.xml。
redissessins.RedisSessionHandlerValve” /> host=“106.15.90.190” port=“6379” database=“0” maxInactiveInterval=“1800”/> <!--redis过期时间默认是60 s,设置session过期时间为1 800 s-->
Redis是键值对类型的内存数据库。同时,用Redis作为MySQL的缓存数据库,能够减小MySQL的压力。服务器先查找Redis服务器中是否有登录用户的信息,有则取出使用,无则查询数据库,查看是否可以验证,将验证后的用户缓存到Redis服务器中,从而减少对数据库的访问。实现的部分代码如下:
//先查询缓存
try {
String json = jedisClient.hget(INDEX_USER, uid + “”);
//查询到结果,把json转换成对象返回
if (StringUtils.isNotBlank(json)) {
User findUser = JsonUtils.
jsonToPojo(json, User.class);
return findUser;}
} catch (Exception e) {
e.printStackTrace();}
//缓存中没有,需要查询数据库
User findUser = userService.login(telphone,password);
//把结果添加到缓存
try {
jedisClient.hset(INDEX_“USER”, uid + “”,JsonUtils.objectToJson(findUser));}
catch (Exception e) {
e.printStackTrace();}
return findUser;
2.2 云服务器框架
云服务器系统开发框架采用Struts+Spring+Hibernate,该框架从职责上分为Web层、业务层、DAO层和持久层。其中,使用Struts作为系统的整体基础架构,负责MVC的分离,在Struts框架的模型部分控制业务跳转。利用Hibernate框架对持久层提供支持。Spring做管理,管理Struts和Hibernate。
系统的基本业务流程为:在Web层中,通过JSP页面实现交互界面,负责接收请求和传送响应,然后Struts根据配置文件(struts-config.xml)将ActionServlet接收到的Request委派给相应的Action处理;在业务层中,管理服务组件的Spring IoC容器负责向Action提供业务模型(Model)组件和该组件的协作对象数据处理(DAO)组件完成业务逻辑,并提供事务处理、缓冲池等容器组件以提升系统性能和保证数据的完整性;而在持久层中则依赖于Hibernate的对象化映射和数据库交互,处理DAO组件请求的数据,并返回处理结果[6]。
该开发模型不仅实现了视图、控制器与模型的彻底分离,而且可以实现业务逻辑层与持久层的分离。不同层之间耦合度小,大大提高了开发效率。
2.3 云服务器功能的实现
云服务器系统主要分为网页后台服务和用户App服务,管理人员通过浏览器访问,查看用户及蓝牙车锁的信息。App服务为Android客户端提供接口,根据App提供的信息对用户和蓝牙车锁信息进行记录,并持久化到MySQL中。系统服务图如图4所示。
App与云服务器的通信主要通过发送HTTP请求,使用轻量级的JSON数据交换格式实现。云服务器为App提供5个接口:用户注册、用户登录、打开车锁、获取用户当前是否打开车锁、关闭车锁。
网页的后台服务中,为防止非登录认证的管理员直接访问某些页面、功能菜单项或action名,使用Struts自定義拦截器,继承Method Filter Interceptor类,并在Struts的配置文件中放行登录方法,登录后将所验证的登录名和密码放到Redis服务器中。若拦截器查询到Redis服务器中有验证过的登录名,则放行;否则,跳转到登录页面。根据Ajax的请求查询数据库,将前台页面不需要的数据排除在外,再将数据以JSON格式返回,前台Ajax的回调函数解析数据并进行地图上的显示。
3 客户端的设计与实现
3.1 客户端功能说明
客户端各功能模块如图5所示。
(1) 登录模块:注册时,本地校验是否为正确的手机号,并向云服务器验证是否已经注册过,经过验证后,向手机号发送验证码,填写验证码进行注册。一经登录,下次使用时App会自动登录。
(2) 用户使用模块:在车辆使用方面,采用手机应用和蓝牙模块建立双向通信达到控制车锁的目的。需要用车时,使用手机蓝牙适配器[7]连接蓝牙模块建立Socket通信通道。只要蓝牙不关闭或者不超过最大通信距离,该通道将会保持,直到手动关闭。通信建立后,手机端通过Socket携带控制命令到蓝牙模块,也可以控制单片机通过串口发送数据到蓝牙模块与手机通信。对于车辆行程监控,需要用户开启后才能进入工作,该功能集成的是百度地图API,调用百度地图的定位功能,通过实时监听手机位置定位车辆。在用户结束用车后会将车辆最后的坐标位置通过手机App上传到云服务器。在车辆使用过程中,若用户开启了路径监控模式,则可以描绘出运行轨迹,同时计算车辆的行驶速度、路程和骑行时间;若用户未开启该模式,则不会进入路径监听模式,百度地图只进行定位。
(3)蓝牙车锁控制模块:手机蓝牙与车锁蓝牙通信后,向云服务器发送HTTP请求,通过解析返回的JSON数据,拿到“钥匙”,从而对车锁进行开关控制。同时,蓝牙车锁端监测到车锁关闭后,向手机发送当前状态,App监听到状态改变,向云服务器请求结束计费,App可以结束用车。
3.2 客户端框架endprint
在Android Studio開发环境下,采用MVC开发架构。视图层接收输入和显示结果,生成App界面;控制层用来处理用户交互的部分,接收到用户的输入后向模型发送数据;模型层调用程序的数据逻辑部分,定义了HTTP通信模块、蓝牙通信模块、数据解析模块等[8,9]。
手机App与车锁蓝牙建立Socket通信,开启一个子线程不断轮询,通过套接字Socket获取字节输入流,解析并获取数据流,将数据使用广播发送给主线程处理。接收蓝牙信息的代码如下:
class ServiceReceiveThread extends Thread{
@Override
public void run(){
byte[] buf=new byte[10];
while (btSocket != null){
BufferedInputStream bis=new BufferedInputStream( btSocket.getInputStream());
int read = bis.read(buf);//接收蓝牙发送的数据
int r=(int)buf[0];
if(r==21){
//发送数据到主线程
handler.sendEmptyMessage(1);
sendBroadcast(newIntent
(“SERVICE_DISCONNECT”));}
sleep(2000);}}
客户端与云服务器通信采用http连接,使用Apache异步网络请求框架AsyncHttpClient,首先在父类Activity中新建该类的实例,子类Activity使用该类向云服务器发送post请求,云服务器返回JSON数据至App[10]。
protected void SendMsgToServer(){
RequestParams params=new RequestParams();
params.put(“telephone”, MyApplication.tel);
params.put(“bluetoothId”,MyUtils.getStrValue(getContext(), “device_addr”));
client.post(GloubleConst.MAIN+GloubleConst.START_CHARGE, params,new AsyncHttpResponseHandler(){
@Override
public void onSuccess(final String content){
if(content.equals(“1”)){
//车辆可以使用
handler.sendEmptyMessage(CAN_USE_BIKE);}
else if(content.equals(“0”)){
//已经在使用
handler.sendEmptyMessage(CANNOT_USE_BIKE)} });}
@Override
public void onFailure(Throwable error, String content){...}//网络连接失败处理
});}
onSuccess()和onFailure()方法接收请求成功或失败的消息,onSuccess()方法的参数content为云服务器返回的JSON数据。
4 蓝牙车锁
蓝牙车锁控制器使用MSP430单片机,内置2.4 G无线发射天线的HC-06蓝牙模块。该蓝牙模块支持两种模式:一种是上电后只能接受命令的从机模式;另一种是主从机一体模式。该系统在主从机一体模式下,通过串口调试工具,利用AT指令修改默认属性。当手机端应用成功连接蓝牙后,即可建立通信。同时,手机端通过套接字向模块写入数据。另外,控制单元也可通过串口发送数据到手机应用端,实现双向通信。
5 客户端和后台中心界面展示
Android客户端以精简、灵活为前提,主要为用户注册登录、匹配车锁、开始/结束用车、行程记录和个人信息界面,Android客户端部分界面如图6所示。
后台管理中心主要包括登录界面、用户信息、车锁信息和车锁地图显示界面。其中,用户信息界面和车锁信息界面可以进行搜索。车锁地图显示界面如图7所示。
6 结 语
本文介绍了基于蓝牙控制的共享单车系统设计和技术,该系统结合云平台、Android平台和蓝牙技术,基于Android手机获取经纬度,并持久化到云服务器中,便于对单车进行维护,为共享单车市场提供一种安全、易实施的设计参考。
参考文献
[1]徐鑫垚.共享单车App后台管理系统的优化[J]. 电子技术与软件工程,2017(4):80-81.
[2]王伟,章民融.基于云架构的智能警务协同指挥系统研究与应用[J].计算机应用与软件,2014, 31(8):67-70.
[3]徐鹂,王耀,王伟聪,等.Moodle系统的集群方案与案例分析[J].计算机应用与软件,2012,29(1):224-229.
[4]杜星.轻量级Web服务器Nginx的理论与技术研究[D]. 南京:南京邮电大学,2016.
[5]曾泉匀.基于Redis的分布式消息服务的设计与实现[D]. 北京:北京邮电大学, 2014.
[6]高蓓蕾.基于ISO管理体系的设备管理系统设计与实现[D]. 南京:南京邮电大学, 2014.
[7]葛会会.基于Android 蓝牙考勤系统的设计与实现[D].抚州:东华理工大学,2016.
[8]陈钰琨,马忠梅,曾礼.Android系统的蓝牙远程控制研究[J].单片机与嵌入式系统应用,2015, 15(1):16-19.
[9]郭健傧,蔡雪松.基于Android平台的公交信息发布终端软件的设计与实现[J].计算机应用与软件,2014,31(9):322-324.
[10]陈玮,秦会斌,曹曙光,等.基于Android平台的智能家居系统设计[J].电子技术应用,2014, 41(10):158-160.endprint