1. 程式人生 > 程式設計 >wamp是什麼? 與websocket有什麼區別?

wamp是什麼? 與websocket有什麼區別?

因為在實驗室的專案中使用到了WAMP,所以去搜了各大網站有關於這個協議的資訊,但是網上的文章少之可憐,最為權威以及正確的也就是WAMP官網啦。所以接下來的知識講解,都是筆者結合自己的實際經驗以及用那點略顯拙劣的英文水平翻譯官網總結出來的,如果有錯誤也希望大家積極的提出來,共同進步!!

同樣,為了更好的驗證程式碼的正確,依舊是貼GitHub地址(但是地址路由器地址全都改啦,這個就需要自己配置安裝啦!!)

一、WAMP是什麼?

1.1 介紹

WAMP(Web Application Messaging Protocol)是一種路由協議,所有元件都連線到WAMP路由器上,WAMP路由器在元件之間執行訊息路由。其設計目的是為應用程式元件之間的實時訊息交換提供開放標準。

WAMP需要一個可靠的,有序的全雙工訊息通道作為傳輸層,預設情況下使用 WebSocket。但是,真正的實現也可以使用與這些特性匹配的其他傳輸,比如原始套接字或HTTP長輪詢與WAMP進行通訊,或者使用RawSocket。

這裡比較一下這兩個傳輸協議:

  • Websocket:使用Websocket傳輸,可以建立持久的雙向連線。訊息沒有HTTP頭,這可以最大限度的減少開銷
  • RawSocket:RawSocket上的WAMP使用的二進位制訊息,不需要事先HTTP握手,具有較小的開銷。但是它最大的缺點就是瀏覽器不允許TCP連線。要在Web瀏覽器上使用客戶端,必須安裝瀏覽器擴充套件,同時另一個缺點是缺少傳輸級壓縮。

1.2 傳遞模式

WAMP提供了兩種訊息傳遞模式:

  • Publish & Subscribe(釋出訂閱)
  • routed Remote Procedure Calls (rRPC)(路由遠端過程呼叫)

釋出和訂閱

釋出和訂閱是一種已建立的訊息傳遞模式。其中元件(訂閱者)通知路由器它想要接收的主題的資訊(也就是它要訂閱主題),然後,另一個元件(釋出者)可以釋出關於某個主題的訊息,最後。路由器將事件分發給所有訂閱該主題的元件。

路由遠端過程呼叫

路由遠端過程呼叫依賴於釋出和預定模式。一個元件(Callee)向路由器提供一個特定的過程。其他元件(Callers)可以呼叫該過程。路由器呼叫Callee上的過程,接收過程的結果,然後將此結果轉發回Caller。

路由RPC和傳統的客戶端-服務端RPC的不同之處在於路由器充當呼叫者和被呼叫者之間的中介,傳統的RPC直接呼叫(通俗講:RPC 是指計算機 A 上的程式,呼叫另外一臺計算機 B 上的程式,其中 A 上的呼叫程式被掛起,而 B 上的被呼叫程式開始執行,當值返回給 A 時,A 程式繼續執行。)

路由RPC的優點

  • 因為所有訊息都在WAMP路由上,因此不再需要在Callee和Caller之間建立直接網路連線或路徑。

二、WAMP中的訊息路由

WAMP在開放的WebSocket協議中提供統一的應用程式路由,該協議適用於不同的語言。

使用WAMP,可以從應用程式元件構建分散式系統,這些元件低耦合實時通訊。

先在這裡列出WAMP的一些特點(優點)

  • 低耦合
  • 基於元件
  • 實時通訊
  • 語言獨立

2.1 低耦合

WAMP提供了我們稱之為應用程式通訊的統一應用程式路由

  • 釋出和訂閱者模式中的事件路由
  • 遠端過程呼叫模式中的呼叫路由

接下來讓我們分別比較傳統方式與WAMP中釋出訂閱模式和路由遠端過程呼叫得出這些特點。

傳統方式

先看一看傳統方式“客戶端-伺服器”的模式,在這種模式中,遠端過程呼叫直接從主叫方到被叫方:

在客戶端-伺服器模型中,呼叫者需要了解被呼叫者所在的位置以及如何訪問它。這就引入了呼叫者和被呼叫這之間的強大耦合,因此應用程式可能很快就會變得很複雜難以維護。

WAMP中的釋出-訂閱模式

在該模式中,釋出者將訊息(主題)傳遞給事件路由,並且訂閱者僅僅是通過對訊息(主題)的訂閱,在事件路由接收到該訊息(主題)後,將訊息(主題)傳遞給訂閱者。

整個過程中,釋出者和訂閱者之間是間接的完成整個過程的,對方都不需要了解彼此

WAMP中的路由遠端過程呼叫

這個過程和釋出-訂閱的模式類似,當呼叫者想要呼叫遠端過程時,它會和呼叫路由通訊,並且只提供呼叫過程的URI以及呼叫引數,然後呼叫路由會在註冊的被呼叫者中進行查詢並呼叫,之後將結果路由回來。兩者之間沒有直接的呼叫。

以上三種模式的比較可以得出,WAMP提供的兩種模式都是通過新增路由器(或者通俗理解就是中介),免去呼叫者和被呼叫者之間的之間交流,以較低元件之間的耦合。這也是WAMP的優點之一了。

2.2基於元件

如果將事件路由(Broker--用於釋出訂閱)和呼叫路由(Dealer--用於路由遠端過程呼叫)組合在一起就會得到WAMP中路由器

如果將這兩者組合成一個路由器,那麼這一個路由器就可以擔任起兩個作用。

2.3 實時

WebSocket是一種新的Web協議,它可以在需要雙向實時通訊時克服HTTP的限制,並且它提供了與Web和瀏覽器相容的雙向實時訊息傳遞,除此之外,還可以在費瀏覽器環境中執行WebSocket。

WAMP是一個正式註冊的WebSocket子協議(執行在WebSocket之上),使用JSON作為訊息序列化格式。

因為WAMP也支援實時雙向通訊。

2.4 語言無關

WAMP擁有許多常見和不常見的語言功能的一流支援。

這也就意味著WAMP可以實現及時使用--無需關心語言。

三、比較WAMP

根據以下六個標準對WAMP以及AJAX、Socket.IO和MQTT進行比較(其它技術沒有使用過,在這不多闡述)

3.1 六個標準

  • 是否支援釋出訂閱模式
  • 是否支援遠端過程呼叫
  • 是否支援路由遠端過程呼叫
  • 是否適用於不同的程式語言
  • 是否有開放式的官方標準
  • 是否本身就執行在網路
技術 釋出訂閱 RPC 路由RPC 網路原生 跨語言 開放標準
WAMP
MQTT - - -
Socket.IO - - - -
AJAX - - -

AJAX

AJAX既不是協議也不是API,而是瀏覽器中JavaScript的程式設計模式,它使用HTTP請求實現前端(瀏覽器)和後端之間類似RPC的通訊。

即使使用AJAX實現了RPC機制,這也是點對點RPC,呼叫不是在不同伺服器或應用程式至今路由,而是嚴格從點(瀏覽器)到點(瀏覽器連線到的伺服器),除此之外,AJAX不提供釋出訂閱模式(可以說是沒有解決伺服器主動推送訊息到伺服器)。

因為AJAX使用普通的HTTP頭資訊,所以它的開銷和限制會比較大。

Socket.IO

Socket.IO是一個用JavaScript編寫的客戶端-服務端(釋出訂閱)的服務實現。使用伺服器端的Node.js和瀏覽器進行通訊。

與WAMP相比,Socket.IO庫允許訂閱不同的主題,具有廣播訊息和訊息名稱空間的功能。二進位制資料傳遞是可能的,但是需要雙方的二外模組(Socket.io-stream)。

Socket.IO不提供遠端過程呼叫。

四、實現

4.1 Library(庫)

為了在不同語言上編寫程式元件,需要選擇適合的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();
複製程式碼

注意

  • 一定要保證訂閱者和釋出者所在的域是一樣的(即要保證ream的值是一樣的)
  • 訂閱者在收到的資料是一個陣列(檔案提供)

模式二:路由遠端呼叫模式

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();
複製程式碼

4.2 Routers(路由器)

官網上提供了很多路由器的庫,因為筆者實驗室用到的是Crossbar,所以對於其他路由庫的配置也不清楚。配置好之後的地址就是筆者在上面xxx.xxx.xxx.xxx:xx所替代的東西。 官網上的配置步驟非常的詳細,即使如此,可能會遇到各種Bug,這就需要就不同的問題自己進行解決啦~~

五、與websocket有什麼區別

講到這裡,其實WAMP的使用以及與Websocket的關係和區別,在上面幾乎都已經說明,如果沒有完全讀懂,說明可能對WebSocket不太熟悉,那麼這裡筆者毛遂自薦瞭解Websocket及Socket.io去讀一讀,再來和這篇文章作對比,就會發現它們的關係和區別啦~~~