三年前,客戶端與服務器端的全雙工雙向通信作為一個很重要的功能被納入到WebSocket RFC 6455協議中。在HTML5中,WebSocket已經成為一個流行詞,大家對這個功能賦予很多構想,很多時候甚至是不切實際的期望。在這篇文章中,我們將重點介紹下如何通過Spring Framework 4.0來構建一個基於 STMOP協議的WebSocket形式的應用。該應用通過 Message Broker向用戶廣播消息,並使用SockJS作為浏覽器前端通信代碼庫。
傳統的Socket交互需要很多項技術的支持,包括Java applet,XMLHttpRequest,Adobe Flash, ActiveXObject, 各種 Comet和服務端發送事件等等。相較於通過如此繁雜的技術來實現Socket交互,WebSockt就顯得簡潔易用得多了。但是別高興得太 早,無論看起來如何誘人,WebSocket現在都還只不過是一個基礎而已。即便它確實為WEB的雙向通信設定了一些重要的標准,但也還只是第一步。要成 為一個成熟的Socket交互方案,WebSocket還需要解決網絡代理設置和浏覽器支持等一系列的問題。
WebSocket和REST對比
當你開始接觸WebSocket應用時,為了找尋你可能會遇到的問題的答案,你就要快速地浏覽一下這篇文章,基於不同的應用類型其中包含了關於 WebSocket是否會替代REST的有趣而不可思議的討論。該類型(WebSocket)應用相對於偶爾工作的應用(web郵件,新聞更新等)擁有更 強大的能力來面對全天候,實時交互(比如游戲、金融、協作化、可視化等)的復雜情況,無論哪種方式,他都是通常人們所熟悉的,而且REST是我們目前通用 的web應用構建風格.在此並非想通過這樣的對比來抵制這些創新,還是讓我們看看能從中學到什麼吧,而這2個要點還是需要我們去觀察才能發現的.
首先,與其他相比,REST是一種在使用無狀態和超媒體(鏈接)時,支持許多URL和少量的HTTP方法的架構方式。與之對應的,WebSocket是一個完全不同的消息模式的架構方式。它不僅僅是一個現有AJAX技術的替代品,更是一個事件驅動的、被動的方法。
第二,REST是基於HTTP的,是在TCP之上建立的一個應用協議,能夠提供給我們用於建立應用邏輯的URLs,HTTP方法,請求或者響應頭,狀態碼,和一些其他的關鍵件。相比之下,WebSocket是一個TCP之上的一個簡單層。它就是一個沒有被定義內容的可以被分解成消息的字節流。在不對一個消息內容做出假設的情況下,一個框架能夠做的很少。當應用做出那樣的假定之後,他們就會圍繞這些假定來創建自己的框架。
WebSocket協議定義了sub-protocols的使用(即更高級別的協議)但沒有引用它。無論哪種方式,應用都需要決定使用什麼消息格式——自定義的、特定框架的或標准的。
總之,一個WebSocket式的應用意味著一個事件驅動型的、響應式的消息傳遞架構。此外工作在WebSocket層次對於大多數應用程序都比較底層,就像現在的大多數Web應用不直接在套接字上編程。
通向實時網絡之路
我們可以從現有的各種框架裡看到好多使用高等消息API,也在底層使用WebSocket,並在必要時依賴一些其他的備選項(比如HTTP流,長輪詢 等)。即便是在今天,也需要依賴於WebSocket和非WebSocket的混合技術。關鍵區別就在於框架是否提供一個單獨的API允許在必要時透明的 回退到非WebSocket傳輸。
一些框架,比如Socket.io和Vert.x提供輕量級的應用組件為事件和消息指定處理者。另一部分,像CometD,通過內部建立一個消息代理來為綁定和接收消息提供通道。像RabbitMQ或者ActiveMQ也提供了直接從浏覽器獲取消息代理的選項。當遇到通信架構時,消息代理模式適合用於構造規模應用的。
Spring4.0的方法
Spring4.0 ——也就是當前的候選版本,預計GA於2013年12月發布——一個目標就是為Websocket類型的應用提供支持。它不僅在基於JSR-356容器之 上提供Websocket API 表現良好,而且也為那些不支持或者不允許使用Websocket的浏覽器和網絡提供了一些候選項。更重要的是,它為在網絡應用中構建Websocket形 式的消息架構提供了基礎。
我們決定使用SockJS protocol作為候選項。它能為這些候選項,提供著最好和最廣泛的傳輸方式。
對於基於WebSocket模式的消息驅動的架構來說,我們也查看了許多現有的方法,我們喜歡這種真正的消息代理的處理能力,也同樣喜歡一個網頁應用使用 中心處理模塊的方式。畢竟,我們必須采用一個消息驅動的架構,但同時我們也是網絡開發者,更習慣建立網頁應用,所以結果不能和我們已知的相差太大。
第一步就是選擇一個消息的格式。有許多簡單消息協議諸如STOMP,MQTT和WAMP。這些都適合應用於網頁客戶端,並為基本的消息模式提供支持。我們 選擇了STOMP,因為它的消息格式是基於HTTP模塊化的,同時它也能被廣泛的支持。然而,我們的處理模塊並沒有過分依賴於STOMP,這個處理模塊也 能被擴展成支持其他簡單協議。
使用STOMP協議能夠讓我們站在WebSocket的肩膀上。它能夠提供一種方法來解析一個消息應該傳遞給誰,我們又對接收什麼樣的消息感興趣。它允許我們像是使用廣播消息代理的插件一樣使用可用的客戶端庫文件,比如stomp.js和msg.js。這就是明顯的優勢。
Spring4提供了STOMP支持。通過兩三行的配置,你就可以在網絡客戶端中把它當做一個輕量級的消息代理。它能夠不需要任何服務器代碼就自動處理綁 定的事件,並允許控制器方法處理進來的消息和綁定事件。這與如何通過Spring MVC映射HTTP請求到控制器方法是相似的。實際上,一個spring MVC控制器能夠被擴展成基於WebSocket的接收STOMP消息的形式。
使用一個全功能的消息代理
在一個全功能的的消息代理中做一個插件也是很容易的。舉個例子,RabbitMQ(或者其他STOMP消息代理),能夠被用來處理客戶端廣播消息的綁定。 在這個場景中,Spring仍然是處於網絡客戶端連接和交換數據的網絡應用層。同時,它也當做一個網關來為RabbitMQ服務,允許消息從應用流向 RabbitMQ,接著轉發給綁定此消息的客戶端。下面的流程圖就是描述這種路徑的:
這個路徑闡述了運行在多服務器和雲環境中的大量應用實例能夠通過RabbitMQ服務廣播到達所有連接的客戶端,而不論此時客戶端連接的是哪一個應用實例。此外,也很容易從HTTP請求處理方法廣播消息到連接的客戶端或者應用的其他部分。
如需更詳盡的技術概覽說明,請移步spring.io上的M2 blog post,運行股票投資組合樣例,或者浏覽spring開發頻道的在線論壇。我們最近發布了RC1候選版。如果你有一個應用的想法,現在是努力去實現和提供反饋絕佳時機。
如果你恰好在倫敦區域或者很容易到達這裡,在11月的14、15日兩天,這裡有一個spring 交流會。屆時會有spring關鍵工程師代表出席,並會發布最偉大的spring4.0框架和我們支持WebSocket的STOMP協議。
Struts2整合Spring方法及原理 http://www.linuxidc.com/Linux/2013-12/93692.htm
基於 Spring 設計並實現 RESTful Web Services http://www.linuxidc.com/Linux/2013-10/91974.htm
Spring-3.2.4 + Quartz-2.2.0集成實例 http://www.linuxidc.com/Linux/2013-10/91524.htm
使用 Spring 進行單元測試 http://www.linuxidc.com/Linux/2013-09/89913.htm
運用Spring注解實現Netty服務器端UDP應用程序 http://www.linuxidc.com/Linux/2013-09/89780.htm
Spring 3.x 企業應用開發實戰 PDF完整高清掃描版+源代碼 http://www.linuxidc.com/Linux/2013-10/91357.htm
Spring 的詳細介紹:請點這裡
Spring 的下載地址:請點這裡