在Event bus的消息實踐上實現實時WEB特性 譯<十三>

TIP:這部分相應的代碼在step-10文件夾中(https://github.com/vert-x3/vertx-guide-for-java-devs)html

在以前的guide中,咱們能夠看到用event bus來鏈接verticles通信,經過傳遞消息的形式,開發者僅僅須要java

註冊消費者來接受和發送訂閱消息。git

SockJS event bus bridge拓展了客戶端,瀏覽器的能力,建立一個分佈式的event bus,不只能夠是集羣中不一樣的verticle實例,也能夠是客戶端瀏覽器上運行的JavaScript程序。所以咱們能夠建立包含瀏覽器和服務端的大的分佈式event bus,在基於消息分佈式應用中須要肯定結果一致性。github

在這個章節,咱們將會修改step-9中的代碼:web

  Markdown的內容渲染髮送到服務端,不發送HTTP請求數據庫

  若是用戶編輯的頁面已經被其餘用戶編輯將提示一個warningnpm

創建 SockJS event bus bridge編程

NOTE:SockJS是個客戶端的JavaScript庫,遵照提供一個相似WebSocket接口的協議,不論實際的瀏覽器或網絡WebSockets,它支持各類不一樣的瀏覽器和服務器之間傳輸,選擇一個運行的。瀏覽器

第一步,咱們須要裝上vertx-web提供的SockJSHandler:服務器

    1.爲Vert.x實例建立一個新的SockJSHandler

    2.容許瀏覽器傳遞的消息來着app.markdown地址,咱們也用這個地址來獲取服務器執行咱們在頁面上執行的編輯的Markdown內容。

    3.容許發送消息到page.saved地址的瀏覽器,咱們將使用這個地址來通知瀏覽器,當頁面被編輯的時候。

    4.配置bridge SockJS traffic到Event bus

    5.處理/ eventbus路徑下全部的請求。

CAUTION:對於大多數應用程序,您可能不但願客戶端JavaScript可以發送任何消息給服務器上的任何處理程序,或其餘瀏覽器。例如:

    1.你可能有一個service在event bus上,能夠訪問或刪除數據的服務,顯然咱們不但願表現差的或惡意的客戶可以刪除數據庫中的全部數據。

    2.咱們沒有必要讓客戶端能夠監放任何事件總線地址。

爲了解決這個問題,一個SockJS bridge將默認拒絕任何信息。這就是爲何它是由你來告訴個人消息是否經過該橋(做爲例外,回覆消息老是容許經過)

在客戶端

如今服務端已經準備好接受消息,咱們將配置客戶端

第一,咱們SockJS和Vert.x event bus JavaScript端須要load,最簡單的方式是從網絡服務中獲取:

NOTE:事件總線客戶端能夠先下載預捆綁應用,可使用maven,npm,bower,甚至wevjars倉庫

而後建立一個EventBus Javascript實例:

var eb = new EventBus(window.location.protocol + "//" + window.location.host + "/eventbus");

發送Markdown內容到event bus 

SockJS bridge 運行起來後,爲了將Markdown內容發送到服務端,咱們須要註冊一個消費者,這個消費者將消息發送到app.markdown地址:

vertx.eventBus().<String>consumer("app.markdown", msg -> {
  String html = Processor.process(msg.body());
  msg.reply(html);
});

這裏沒有什麼新東西,咱們以前已經建立了一個event bus消費者,而後咱們看看在付端端修改了什麼代碼:

    1.reply程序方法有兩個參數:一個error(若是須要)和一個reply對象,reply對象的內容包含在body中

    2.由於 event bus client沒有被AngularJS管理,$scope.$apply用於生命週期的回調

    3.當咱們使用$http,藉助updateRendering來處理HTML結果。

誠然,這代碼和HTTP endpoint代碼相似,然而好處是不依賴於代碼的行數編號。事實上,若是你在 event bus進行服務端的通訊,bridge透明的處理分佈的註冊消費者的消息。所以,當Vert.x運行在集羣模式中,這瀏覽不是聯繫一個當以的服務器程序(除了sockjs鏈接),更重要的是對服務器的鏈接是永遠不會關閉,因此HTTP / 1.1這節省了爲每一個請求創建一個TCP鏈接,這多是有用的,若是你有服務器和客戶端之間的交流不少。

當頁面被他人修改提示Warning

在不少的應用中,咱們老是以最後的提交爲準則來處理這個衝突:當兩個用戶在同一個時間編輯相同的資源,最後一個提交保存的會覆蓋前個的修改。

針對這個問題咱們有多重方式,像實體版本,或者分佈式的拓展字段。然而,讓咱們堅持一個簡單的解決方案,看看咱們如何可以通知用戶當變化,至少他獲得一個機會來處理狀況。一旦數據庫中的內容修改,用戶能夠決定最好的行動是什麼:改寫或從新加載。

咱們須要添加一個 alert alert-warning 信息到 div中,可是咱們僅僅在pageModified設置爲true的狀況下展現。

<div class="col-md-12">
  <div class="alert alert-warning ng-class:{'invisible': !pageModified};" role="alert">
    The page has been modified by another user.
    <a href="#" ng-click="load(pageId)">Reload</a>
  </div>
</div>

當頁面被保存的時候pageModified設置爲true,咱們從page.saved地址註冊event bus程序:

    1.咱們不想打印警告若是咱們修改本身的內容,咱們須要一個客戶端標識符

    2.回調地址將會出發在消息被page.saved地址接收

    3.檢查body是否爲空

    4.肯定event是關聯到當前wiki 頁面

    5.肯定沒有修改

    6.設置pageModified true

當頁面的額內容被保存到數據庫的時候須要發送消息:

    1.rxSavePage返回Single<Void>對象,成功後發送一個event

    2.消息包含一個頁面標識

    3.消息包含一個客戶端標識

    4.event被髮送到page.saved 地址

若是咱們打開應用在兩個不一樣的tabs,能夠是同一個瀏覽器或者是不一樣的,選擇相同的頁面,在其中一個更新信息,另外一個個提示警告信息:

咱們能夠簡單的拓展SockJS bridge爲了其餘目的,像有多少用戶在同一個頁面,支持一個實時聊天的窗口等等。關鍵的一點是,在服務器和客戶端共享相同的編程模型,經過消息傳遞的事件總線。

原文連接:http://vertx.io/docs/guide-for-java-devs/

個人微信公衆號:

相關文章
相關標籤/搜索