丁振凡
(華東交通大學信息工程學院,江西 南昌 330013)
?
基于Spring4+HTML5的實時監(jiān)控應用通信與顯示處理
丁振凡
(華東交通大學信息工程學院,江西 南昌 330013)
針對某企業(yè)生產(chǎn)線遠程數(shù)據(jù)監(jiān)測應用中消息推送與顯示處理的問題,提出基于Sping4+HTML5的實現(xiàn)方案.采用WebSocket技術(shù)實現(xiàn)瀏覽器與Web服務器的雙向消息通信.研究了Spring的WebSocket服務配置和實現(xiàn)消息推送的處理流程,描述了客戶方與服務方如何建立SockJS連接,以及實現(xiàn)基于STOMP的消息發(fā)布/訂閱處理的具體方法.將消息推送封裝為REST風格的Web服務,方便調(diào)用者發(fā)布消息.系統(tǒng)采用HTML5的Canvas實現(xiàn)數(shù)據(jù)的實時顯示處理,可在同一畫面中顯示各種顏色的曲線.Sping4+HTML5方案具有配置簡單、應用靈活、運行效率高等特點,在實際應用中取得了很好的效果.
HTML5;Spring4;WebSocket;Canvas;實時監(jiān)控;SockJS
隨著Web應用的不斷深入,在Web界面中實時應用的顯示處理一直是研究人員關(guān)注的問題,最大的難點是實時數(shù)據(jù)以何種方式送瀏覽器顯示的問題.由HTTP協(xié)議的特點,瀏覽器與Web服務器之間的連接不能持久保持,瀏覽器與Web服務器的通信是基于請求/響應的方式.為了持續(xù)獲取來自生產(chǎn)線的數(shù)據(jù),最早是頁面定時刷新的方法,后來出現(xiàn)了基于AJAX的定時輪詢方式,這種拉方式效率不高,最大問題是客戶端請求的頻率與服務器端數(shù)據(jù)更新頻率通常會不一致,從而造成網(wǎng)絡流量浪費.理想的方法是采用推方式,由服務器將數(shù)據(jù)推送到瀏覽器顯示,但推方式在技術(shù)處理上一直不盡人意,例如采用JAVA applet通信,現(xiàn)在瀏覽器普遍不支持Applet技術(shù).HTML5的出現(xiàn)為實時應用的通信、顯示處理提供了很好的支撐.HTML5 WebSocket 規(guī)范定義了WebSocket API,支持頁面使用WebSocket 協(xié)議與遠程主機進行全雙工的通信[1].基于WebSocket的通信,可通過消息訂閱的推送方式獲取數(shù)據(jù),實現(xiàn)更為高效的數(shù)據(jù)傳輸.WebSocket通過HTTP的子協(xié)議來實現(xiàn)消息的傳送,STOMP是典型采用的簡單消息傳送協(xié)議.WebSocket目前已經(jīng)得到IE9,F(xiàn)irefox4,Chrome4 等瀏覽器,以及Jetty7和Tomcat8等服務器的支持.HTML5的Canvas提供的豐富圖形功能可支持瀏覽器上圖形顯示編程處理.在智能手機平臺也可利用WebSocket結(jié)合HTML5實現(xiàn)實時監(jiān)控[2].
Spring是一種輕量級的開源框架,它具有支持Bean屬性的依賴注入、支持面向切面編程等眾多特點.Spring Web編程提供了基于REST風格的MVC模式,可方便編寫基于REST風格的Web服務.Spring MVC將Web應用程序抽象為模型、視圖和控制器3個部分.通過DispatcherServlet這個特殊的控制器處理用戶的請求,該控制器在處理HTTP請求時根據(jù)Mapping信息查找對應的控制器,實現(xiàn)控制分派[3].2013年底正式推出的Spring4中增加了對WebSocket的支持,并支持STOMP,通過開啟SockJS的服務,同時提供相應的URL映射,就可支持基于WebSocket的消息通信.
應用系統(tǒng)是用瀏覽器顯示2條生產(chǎn)線上設備的實時狀態(tài)信息.系統(tǒng)架構(gòu)如圖1所示.
圖1 生產(chǎn)線實時監(jiān)控系統(tǒng)的架構(gòu)
通過PLC組件獲取生產(chǎn)線上各種設備的工作狀態(tài)參數(shù)(如溫度、壓力變化),并通過其通信模塊與Web服務器的串口通信.每個串口與1條PLC組件的通信模塊進行連接.服務器方的串口通信模塊采用Java的comm組件編程[4].串口在收到消息后,經(jīng)過分析處理,再調(diào)用Spring MVC實現(xiàn)的REST風格的Web服務將消息借助WebSocket通道推送到瀏覽器顯示.服務端的消息代理(Message Broker)實現(xiàn)與瀏覽器之間的基于發(fā)布/訂閱的消息通信.
系統(tǒng)采用Maven工程設計,為支持WebSocket,需要添加Spring-messaging,Spring-WebSocket,Jackson-databind等依賴.Spring的配置可通過注解或XML方式定義[3].采用注解方式配置Spring的控制器和WebSocket.系統(tǒng)中面向消息的WebSocket應用與HTTP應用并存,作為一個Web應用項目,要進行Servlet的配置,在Servlet的配置中加入如下2行,表示支持注解方式定義配置及指定查找配置程序的包路徑信息:
2.1 Spring 的WebSocket配置
以下注解配置指定采用基于內(nèi)存的簡單消息代理.其中:“/topic”是簡單代理的端點,所有發(fā)送給客戶端的消息要以“/topic”為前綴;“/app”是瀏覽器請求編碼的前綴,所有由客戶發(fā)送給消息代理的消息要以“/app”為前綴;“/monitor”是websocket連接端點,客戶與服務器建立WebSocket連接時通過“/wxm/monitor”,wxm為Web應用路徑名.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
public void configureMessageBroker(MessageBrokerRegistry config){
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
public void registerStompEndpoints(StompEndpointRegistry r){
r.addEndpoint("/monitor").withSockJS();
}
}
根據(jù)需要還可以將ActiveMQ和RabbitMQ等消息隊列代理與WebSocket進行捆綁,用消息代理作為中繼,這樣可利用RabbitMQ的Web監(jiān)控功能監(jiān)控應用的消息收發(fā)狀況,同時也方便基于消息的應用集成處理.在配置代碼中只需作如下改動:
config.enableStompBrokerRelay("/topic").
2.2 WebSocket通信與Spring MVC的整合
在控制器的配置中,允許2類Mapping并存,一種是@RequestMapping,接收來自瀏覽器的HTTP請求,注解參數(shù)為REST風格的路徑信息;另一種是@MessageMapping,接收來自瀏覽器發(fā)送的WebSocket消息.在Spring中,用REST風格的路徑標識來表示消息目標,該目標對應消息隊列中的主題.@MessageMapping的注解參數(shù)代表消息源的目標,通過其注解方法參數(shù)傳遞消息對應的Java對象.Spring的WebSocket和SockJS并不依賴Spring MVC,它是通過SockJSHTTPRequestHandler將WebSocket支持集成到HTTP服務環(huán)境.
在以下控制器定義中列出了2個方法:(1)方法line1用于將生產(chǎn)線1的消息進行推送,來自請求參數(shù)message的消息是實體類ProduceLine中數(shù)據(jù)對象的Json表示的串,ProduceLine類中封裝有代表生產(chǎn)線的各種參數(shù)數(shù)據(jù).應用中采用Google公司Gson類實現(xiàn)對Java對象的Json串行化處理,以方便Java對象的傳遞.借助自動依賴注入得到的SimpMessagingTemplate對象,用其convertAndSend方法可發(fā)送消息給“/topic/line1”主題.(2)方法curve用于進入顯示生產(chǎn)線的參數(shù)變化曲線的頁面.
@Controller
public class MvcController{
@Autowired private SimpMessagingTemplate template;
@RequestMapping("/info/line1*")
@ResponseBody
public String line1(@RequestParam("message") String message){
GsonJson=new Gson();
ProduceLine me=json.fromJson(message,ProduceLine.class); ∥由Json串得到Java對象
template.convertAndSend("/topic/line1",me); ∥發(fā)布消息給/topic/line1主題
return "message send ";
}
@RequestMapping("/curve*") ∥監(jiān)視生產(chǎn)線參數(shù)頁面
public String curve(@RequestParam("line") String line,Model m){
m.addAttribute("line",line); ∥生產(chǎn)線編號
return "curveinfo"; ∥用curveinfo.jsp視圖顯示
}
}
圖2 應用的消息通信處理流程
通過定義REST風格的Web服務對消息發(fā)送進行封裝,可以在任何需要的地方調(diào)用該服務進行消息的發(fā)送.圖2給出了應用的消息通信處理流程.
利用Spring的RestTemplate可調(diào)用上面方法line1對應的REST風格的Web服務[3],應用中只要調(diào)用以下定義的sendProduceLine方法就可將生產(chǎn)線數(shù)據(jù)推送給客戶:
public static void sendProduceLine(ProduceLine data){
RestTemplate template=new RestTemplate();
GsonJson=new Gson();
String msg=Json.toJson(data);∥Java對象轉(zhuǎn)Json串
template.getForObject("http:∥localhost:8080/wxm/info/line1?message={message}",String.class,new Object[]{msg});
}
Spring的WebSocket也可接收客戶方發(fā)送的消息并轉(zhuǎn)發(fā)該消息.對于控制器定義的帶@MessageMapping注解的方法,可用@SendTo注解加在方法頭前,表示將方法的結(jié)果作為消息負載發(fā)送給指定主題的訂閱者.例如,以下Mapping方法,服務端收到客戶瀏覽器發(fā)送給目標“app/hello”的消息后,將在消息前增加“hello:”,再轉(zhuǎn)發(fā)給“/topic/welcome”的訂閱者,這種方式可用于實時聊天等應用:
@MessageMapping("/hello")
@SendTo("/topic/welcome")
public String welcome(String message) throws Exception{
return new String("Hello:"+message+"!");
}
為了支持基于SockJS的Stomp消息通信,客戶方要用到“sockjs-0.3.4.js”和“stomp.js”這2個js文件.客戶方通過執(zhí)行以下Javascript腳本可建立與服務器的WebSocket連接,在Stomp通信中,使用最多的命令是發(fā)送消息命令send和訂閱消息命令subscribe:
var Socket=new SockJS(′/wxm/monitor′);
stompClient=Stomp.over(Socket);
stompClient.connect({},
function(frame){
stompClient.subscribe(′/topic/line${line}′,
function(produceLine){
obj= Json.parse(produceLine.body); ∥取得封裝在消息中的Java對象
drawCurve(1,1,1,obj.temperature1); ∥繪制溫度曲線
…
});
}
注意,客戶方在指定連接的WebSocket端點(endpoint)時要加上Web應用名,這里為“wxm/monitor”.連接成功后將執(zhí)行function(frame)方法,進而通過調(diào)用StompClient對象的subscribe方法訂閱主題為“/topic/line${line}”的消息,這里,${line}是來自MVC模型的代表生產(chǎn)線編號的數(shù)據(jù),其值為1或2.消息broker在收到主題對應的消息時將發(fā)送給瀏覽器,function(produceLine)是消息到達時觸發(fā)執(zhí)行的消息處理函數(shù),它將通過Json.parse方法對消息體進行分析,提取設備的溫度值,調(diào)用drawCurve方法繪制出溫度實時變化曲線.
需要說明的是,這里為清晰起見,將所有主題描述均加上了“/topic”前綴.若用ActiveMQ作為代理中繼,則可在ActiveMQ的監(jiān)控頁面看到主題名稱僅為“/topic”之后的部分(如line1).由于“/topic”是代理的端點,因此實際發(fā)送消息給主題時必須以“/topic”為前綴.
瀏覽器與服務器間這種基于發(fā)布/訂閱的消息推送機制是一種高效靈活的數(shù)據(jù)傳遞方式.來自生產(chǎn)線的數(shù)據(jù)不僅可以同時提供給不同瀏覽器的訂閱者,同一個頁面中也可以通過訂閱不同的主題獲取來自不同發(fā)布者的數(shù)據(jù)(如應用系統(tǒng)中就有一個頁面要同時顯示來自2條生產(chǎn)線的數(shù)據(jù)).訂閱者只需進行1次訂閱就可不斷接收數(shù)據(jù),數(shù)據(jù)的推送頻率由提供者決定,消息通信效率很高,避免了AJAX等輪詢技術(shù)需要每次發(fā)送請求來獲取數(shù)據(jù)所帶來的低效問題.
以往Web實時監(jiān)測應用,大多采用SVG或VML實現(xiàn)圖形繪制[5-6],編程較復雜,應用也有局限.本系統(tǒng)采用HTML5的Canvas實現(xiàn)數(shù)據(jù)變化曲線的繪制,代碼簡練.由于實際應用中需要觀察的監(jiān)測參數(shù)的數(shù)量眾多,每個參數(shù)有自己的變化曲線,考慮到這些曲線的繪制方法是一樣的,只是顏色不同,繪制的畫布不同,因此合并用一個函數(shù)drawCurve實現(xiàn)繪制.繪制曲線時要記下上一點的位置,各條曲線的上一點位置安排存儲在2個全局數(shù)組x和y中,且給y數(shù)組的元素賦初值0,給x數(shù)組的元素賦初值為坐標軸起點在Canvas中的實際位置.定義一個全局字符串類型的數(shù)組color,存儲要使用的幾種顏色值.
function drawCurve(index,canvas,colorIndex,value){
if (y[index]!=0){
var c=document.getElementById("myCanvas"+canvas);
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.strokeStyle=color[colorIndex]; ∥設置線條顏色
ctx.moveTo(x[index],170-y[index]);
var x2=x[index]+1; ∥x坐標每次增加1
ctx.lineTo(x2,170-value);
ctx.stroke(); ∥線條的填充繪制
if (x2>450){ ∥繪制到畫布最右邊位置,清除畫面
ctx.clearRect(36,0,450,180);
x2=36;
}
x[index]=x2;
}
y[index]=value; ∥記下新位置點
}
Canvas實現(xiàn)曲線繪制的方法很簡單,用moveTo方法定位起點,用lineTo方法定位要經(jīng)過的點,用stroke()方法實現(xiàn)線條填充繪制.
Spring4+HTML5的Web實時應用設計方案具有廣泛的應用空間.客戶端和服務方用基于SockJS連接的Stomp協(xié)議實現(xiàn)數(shù)據(jù)的傳送,通過消息的發(fā)布/訂閱機制實現(xiàn)生產(chǎn)線數(shù)據(jù)的遠程監(jiān)測,并用HTML5的Canvas實現(xiàn)圖形繪制.Spring4通過很好的封裝設計,可讓編程者容易地配置基于SockJS的消息代理服務.本設計是將消息推送封裝為Web服務,其好處是可以實現(xiàn)應用部件之間的松耦合.實踐證明,該方案具有配置簡單、編程方便、運行效率高等特點.
[1] 李慧云,何震葦,李 麗,等.HTML5技術(shù)與應用模式研究[J].電信科學,2012,28(5):24-29.
[2] 張延召,陳少紅.基于智能手機平臺的實時控制系統(tǒng)[J].計算機應用與軟件,2013,30(7):236-239.
[3] 丁振凡.Spring3.x編程技術(shù)與應用[M].北京:北京郵電大學出版社,2013.
[4] 丁振凡,王小明,鄧建明,等.基于Java的串口通信應用編程[J].微型機與應用,2012,31(13):84-86.
[5] 楊 斌,張利欣,章立軍,等.基于SVG的Web遠程實時監(jiān)測客戶端研究[J].計算機應用研究,2010,27(6):2 144-2 146.[6] 劉 丹,李 剛,田銀枝,等.利用VML和SVG繪制軍標箭頭符號的算法實現(xiàn)[J].測繪科學,2014,39(4):115-118.
(責任編輯 向陽潔)
Communication and Display Processing for the Real-Time Monitoring Application Based on Spring4+HTML5
DING Zhenfan
(School of Information Engineering,East China Jiaotong University,Nanchang 330013,China)
In view of message pushing and display processing problems in the remote data monitoring application for the production line in one enterprise,this paper proposes an implementation scheme based on HTML5 and the Spring framework 4.WebSocket technology is used for the message transfer on the two way communication between the web browser and Web server.The Spring WebSocket service configuration and the processing scheme for message pushing are studied.The creation of SockJS connection between the client and server and the processing method for STOMP message publishing/subscription are described.By providing the REST style Web services with the messages pushing process,it is convenient for the caller to publish message.The system adopts Canvas in HTML5 for the real time data display processing,thus achieving the effect of displaying curves of various colors in the same screen.The Spring4+HTML5 scheme has the advantages of easy configuration,flexible application and efficient operation and can get satisfactory practical effects.
HTML5;Spring4;WebSocket;Canvas;real-time monitoring;SockJS
1007-2985(2015)04-0018-05
2014-10-12
丁振凡(1965—),男,江西豐城人,華東交通大學信息工程學院教授,碩士生導師,主要從事云計算、語義Web、計算機輔助教學等研究.
TP393
A
10.3969/j.issn.1007-2985.2015.04.005