王風雷+秦會斌+崔佳冬
摘 要:為了改善共享單車機械鎖密碼不安全、電子鎖成本高的不足,設計并實現了基于藍牙控制的共享單車系統。單車車鎖采用藍牙與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