由於在實驗室的項目中使用到了WAMP,因此去搜了各大網站有關於這個協議的信息,可是網上的文章少之可憐,最爲權威以及正確的也就是WAMP官網啦。因此接下來的知識講解,都是筆者結合本身的實際經驗以及用那點略顯拙劣的英文水平翻譯官網總結出來的,若是有錯誤也但願你們積極的提出來,共同進步!!html
一樣,爲了更好的驗證代碼的正確,依舊是貼GitHub地址(可是地址路由器地址全都改啦,這個就須要本身配置安裝啦!!) 前端
WAMP(Web Application Messaging Protocol)是一種路由協議,全部組件都鏈接到WAMP路由器上,WAMP路由器在組件之間執行消息路由。其設計目的是爲應用程序組件之間的實時消息交換提供開放標準。git
WAMP須要一個可靠的,有序的全雙工消息通道做爲傳輸層,默認狀況下使用 WebSocket。可是,真正的實現也可使用與這些特性匹配的其餘傳輸,好比原始套接字或HTTP長輪詢與WAMP進行通訊,或者使用RawSocket。github
這裏比較一下這兩個傳輸協議:web
WAMP提供了兩種消息傳遞模式:編程
發佈和訂閱是一種已創建的消息傳遞模式。其中組件(訂閱者)通知路由器它想要接收的主題的信息(也就是它要訂閱主題),而後,另外一個組件(發佈者)能夠發佈關於某個主題的消息,最後。路由器將事件分發給全部訂閱該主題的組件。後端
路由遠程過程調用依賴於發佈和預約模式。一個組件(Callee)向路由器提供一個特定的過程。其餘組件(Callers)能夠調用該過程。路由器調用Callee上的過程,接收過程的結果,而後將此結果轉發回Caller。數組
路由RPC和傳統的客戶端-服務端RPC的不一樣之處在於路由器充當呼叫者和被呼叫者之間的中介,傳統的RPC直接調用(通俗講:RPC 是指計算機 A 上的進程,調用另一臺計算機 B 上的進程,其中 A 上的調用進程被掛起,而 B 上的被調用進程開始執行,當值返回給 A 時,A 進程繼續執行。)瀏覽器
路由RPC的優勢:bash
WAMP在開放的WebSocket協議中提供統一的應用程序路由,該協議適用於不一樣的語言。
使用WAMP,能夠從應用程序組件構建分佈式系統,這些組件低耦合並實時通訊。
先在這裏列出WAMP的一些特色(優勢)
WAMP提供了咱們稱之爲應用程序通訊的統一應用程序路由:
接下來讓咱們分別比較傳統方式與WAMP中發佈訂閱模式和路由遠程過程調用得出這些特色。
先看一看傳統方式「客戶端-服務器」的模式,在這種模式中,遠程過程調用直接從主叫方到被叫方:
在客戶端-服務器模型中,調用者須要瞭解被調用者所在的位置以及如何訪問它。這就引入了調用者和被調用這之間的強大耦合,所以應用程序可能很快就會變得很複雜難以維護。在該模式中,發佈者將消息(主題)傳遞給事件路由,而且訂閱者僅僅是經過對消息(主題)的訂閱,在事件路由接收到該消息(主題)後,將消息(主題)傳遞給訂閱者。
整個過程當中,發佈者和訂閱者之間是間接的完成整個過程的,對方都不須要了解彼此
這個過程和發佈-訂閱的模式相似,當調用者想要調用遠程過程時,它會和呼叫路由通訊,而且只提供調用過程的URI以及調用參數,而後呼叫路由會在註冊的被調用者中進行查找並調用,以後將結果路由回來。二者之間沒有直接的調用。
以上三種模式的比較能夠得出,WAMP提供的兩種模式都是經過添加路由器(或者通俗理解就是中介),免去調用者和被調用者之間的之間交流,以較低組件之間的耦合。這也是WAMP的優勢之一了。
若是將事件路由(Broker--用於發佈訂閱)和呼叫路由(Dealer--用於路由遠程過程調用)組合在一塊兒就會獲得WAMP中路由器。
若是將這二者組合成一個路由器,那麼這一個路由器就能夠擔任起兩個做用。
WebSocket是一種新的Web協議,它能夠在須要雙向實時通訊時克服HTTP的限制,而且它提供了與Web和瀏覽器兼容的雙向實時消息傳遞,除此以外,還能夠在費瀏覽器環境中運行WebSocket。
WAMP是一個正式註冊的WebSocket子協議(運行在WebSocket之上),使用JSON做爲消息序列化格式。
由於WAMP也支持實時雙向通訊。
WAMP擁有許多常見和不常見的語言功能的一流支持。
這也就意味着WAMP能夠實現及時使用--無需關心語言。
根據如下六個標準對WAMP以及AJAX、Socket.IO和MQTT進行比較(其它技術沒有使用過,在這很少闡述)
技術 | 發佈訂閱 | RPC | 路由RPC | 網絡原生 | 跨語言 | 開放標準 |
---|---|---|---|---|---|---|
WAMP | √ | √ | √ | √ | √ | √ |
MQTT | √ | - | - | - | √ | √ |
Socket.IO | √ | - | - | √ | - | - |
AJAX | - | √ | - | √ | √ | - |
AJAX既不是協議也不是API,而是瀏覽器中JavaScript的編程模式,它使用HTTP請求實現前端(瀏覽器)和後端之間相似RPC的通訊。
即便使用AJAX實現了RPC機制,這也是點對點RPC,調用不是在不一樣服務器或應用程序至今路由,而是嚴格從點(瀏覽器)到點(瀏覽器鏈接到的服務器),除此以外,AJAX不提供發佈訂閱模式(能夠說是沒有解決服務器主動推送消息到服務器)。
由於AJAX使用普通的HTTP頭信息,因此它的開銷和限制會比較大。
Socket.IO是一個用JavaScript編寫的客戶端-服務端(發佈訂閱)的服務實現。使用服務器端的Node.js和瀏覽器進行通訊。
與WAMP相比,Socket.IO庫容許訂閱不一樣的主題,具備廣播消息和消息命名空間的功能。二進制數據傳遞是可能的,可是須要雙方的二外模塊(Socket.io-stream)。
Socket.IO不提供遠程過程調用。
爲了在不一樣語言上編寫程序組件,須要選擇適合的WAMP庫。也就是說,我使用不一樣的語言,要選擇該語言版本的庫。
這裏只說一下 AutobahnJS,該庫能夠運行在JavaScript、HTML5以及NodeJS環境中。
貼一個GitHub地址,詳細介紹參看這個網址就能夠了,其實它的使用理解下來與Socket.IO差很少,只不過在使用以前須要在服務器上安裝路由器(下面會講),這裏就貼一下基本使用的代碼。
publicer(發佈者)代碼:
//引入庫
var autobahn = require('autobahn');
//建立鏈接
var connection = new autobahn.Connection({
url: 'ws://xxx.xxx.xxx:xxx/ws', //路由器的地址
realm: 'realm1' //域(相似於Socket.io中的命名空間)
});
//監聽鏈接
connection.onopen = function (session) {
console.log('鏈接成功');
//發佈消息,第一個參數爲主題,第二個參數爲發佈內容
session.publish('wamptopic', ['Hello,World!']);
};
//打開鏈接
connection.open();
複製代碼
receiver(訂閱者)代碼:
//引入庫
var autobahn = require('autobahn');
//建立鏈接
var connection = new autobahn.Connection({
url: 'ws://xxx.xxx.xxx.xxx:xxx/ws', //路由器的地址
realm: 'realm1' //域(相似於Socket.io中的命名空間)
});
//監聽鏈接
connection.onopen = function (session) {
function onEvent(args) {
var msg = args[0];
console.log(" received: " + msg);
}
//訂閱主題,第一個參數是主題,第二個參數是接收信息的回調函數
session.subscribe('wamptopic', onEvent)
};
//打開鏈接
connection.open();
複製代碼
注意
callee(調用者)
//引入庫
var autobahn = require('autobahn');
//建立鏈接
var connection = new autobahn.Connection({
url: 'ws://xxx.xxx.xxx.xxx:xxx/ws', //路由器的地址
realm: 'realm1' //域(相似於Socket.io中的命名空間)
});
//監聽鏈接
connection.onopen = function (session) {
function onEvent(args) {
return args[0] + args[1];
}
//訂閱主題,第一個參數是主題,第二個參數是接收、處理並返回信息的回調函數
session.register('wamptopic', onEvent)
};
//打開鏈接
connection.open();
複製代碼
caller(被調用者)
//引入庫
var autobahn = require('autobahn');
//建立鏈接
var connection = new autobahn.Connection({
url: 'ws://xxx.xxx.xxx.xxx:xxx/ws', //路由器的地址
realm: 'realm1' //域(相似於Socket.io中的命名空間)
});
//監聽鏈接
connection.onopen = function (session) {
console.log('鏈接成功');
//發佈消息,第一個參數爲主題,第二個參數爲傳遞的參數,以後是接收調用的返回結果
session.call('wamptopic', [2, 3]).then((res) => {
console.log('結果', res)
})
};
//打開鏈接
connection.open();
複製代碼
官網上提供了不少路由器的庫,由於筆者實驗室用到的是Crossbar,因此對於其餘路由庫的配置也不清楚。配置好以後的地址就是筆者在上面xxx.xxx.xxx.xxx:xx所替代的東西。 官網上的配置步驟很是的詳細,即便如此,可能會遇到各類Bug,這就須要就不一樣的問題本身進行解決啦~~
講到這裏,其實WAMP的使用以及與Websocket的關係和區別,在上面幾乎都已經說明,若是沒有徹底讀懂,說明可能對WebSocket不太熟悉,那麼這裏筆者毛遂自薦瞭解Websocket及Socket.io去讀一讀,再來和這篇文章做對比,就會發現它們的關係和區別啦~~~