天天看點

STOMP 用戶端 API 整理

原創 2017年08月31日 13:27:22

  • 标簽:
  • api /
  • websocket /
  • stomp /
  • 3187
  • 編輯
  • 删除

參考教程:http://jmesnil.net/stomp-websocket/doc/

在使用 stomp.js 時,能找到的較完整的 API 說明基本都是英文,中文資料比較少,是以,參考上邊的教程做了以下的筆記和總結

介紹

STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的簡單文本協定

WebSocket是一個消息架構,不強制使用任何特定的消息協定,它依賴于應用層解釋消息的含義;

與處在應用層的HTTP不同,WebSocket處在TCP上非常薄的一層,會将位元組流轉換為文本/二進制消息,是以,對于實際應用來說,WebSocket的通信形式層級過低,是以,可以在 WebSocket 之上使用 STOMP協定,來為浏覽器 和 server間的 通信增加适當的消息語義。

如何了解 STOMP 與 WebSocket 的關系:

1) HTTP協定解決了 web 浏覽器發起請求以及 web 伺服器響應請求的細節,假設 HTTP 協定 并不存在,隻能使用 TCP 套接字來 編寫 web 應用,你可能認為這是一件瘋狂的事情;

2) 直接使用 WebSocket(SockJS) 就很類似于 使用 TCP 套接字來編寫 web 應用,因為沒有高層協定,就需要我們定義應用間所發送消息的語義,還需要確定連接配接的兩端都能遵循這些語義;

3) 同 HTTP 在 TCP 套接字上添加請求-響應模型層一樣,STOMP 在 WebSocket 之上提供了一個基于幀的線路格式層,用來定義消息語義;

STOMP幀

STOMP幀由指令,一個或多個頭資訊、一個空行及負載(文本或位元組)所組成;

其中可用的COMMAND 包括:

CONNECT、SEND、SUBSCRIBE、UNSUBSCRIBE、BEGIN、COMMIT、ABORT、ACK、NACK、DISCONNECT;

例:

發送消息

SEND

destination:/queue/trade

content-type:application/json

content-length:44

{“action”:”BUY”,”ticker”:”MMM”,”shares”,44}^@

訂閱消息

SUBSCRIBE

id:sub-1

destination:/topic/price.stock.*

^@

伺服器進行廣播消息

MESSAGE

message-id:nxahklf6-1

subscription:sub-1

destination:/topic/price.stock.MMM

{“ticker”:”MMM”,”price”:129.45}^@

用戶端 API

引入stomp.js

<script type="application/javascript" src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>           
  • 1

發起連接配接

用戶端可以通過使用Stomp.js和sockjs-client連接配接

// 建立連接配接對象(還未發起連接配接)
var socket=new SockJS("/spring-websocket-portfolio/portfolio");

// 擷取 STOMP 子協定的用戶端對象
var stompClient = Stomp.over(socket);

// 向伺服器發起websocket連接配接并發送CONNECT幀
stompClient.connect(
    {},
function connectCallback (frame) {
    // 連接配接成功時(伺服器響應 CONNECTED 幀)的回調方法
        document.getElementById("state-info").innerHTML = "連接配接成功";
        console.log('已連接配接【' + frame + '】');
        stompClient.subscribe('/topic/getResponse', function (response) {
            showResponse(response.body);
        });
    },
function errorCallBack (error) {
    // 連接配接失敗時(伺服器響應 ERROR 幀)的回調方法
        document.getElementById("state-info").innerHTML = "連接配接失敗";
        console.log('連接配接失敗【' + error + '】');
    }
);           
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

說明:

1) socket連接配接對象也可通過WebSocket(不通過SockJS)連接配接

var socket=new WebSocket("/spring-websocket-portfolio/portfolio");           

2) stompClient.connect()方法簽名:

client.connect(headers, connectCallback, errorCallback);           

其中

headers表示用戶端的認證資訊,如:

var headers = {
  login: 'mylogin',
  passcode: 'mypasscode',
  // additional header
  'client-id': 'my-client-id'
};           

若無需認證,直接使用空對象 “{}” 即可;

connectCallback 表示連接配接成功時(伺服器響應 CONNECTED 幀)的回調方法;

errorCallback 表示連接配接失敗時(伺服器響應 ERROR 幀)的回調方法,非必須;

斷開連接配接

若要從用戶端主動斷開連接配接,可調用 disconnect() 方法

client.disconnect(function () {
   alert("See you next time!");
};           

該方法為異步進行,是以包含了回調參數,操作完成時自動回調;

心跳機制

若使用STOMP 1.1 版本,預設開啟了心跳檢測機制,可通過client對象的heartbeat field進行配置(預設值都是10000 ms):

client.heartbeat.outgoing = 20000;  // client will send heartbeats every 20000ms
client.heartbeat.incoming = 0;      // client does not want to receive heartbeats from the server
// The heart-beating is using window.setInterval() to regularly send heart-beats and/or check server heart-beats           

發送資訊

連接配接成功後,用戶端可使用 send() 方法向伺服器發送資訊:

client.send(destination url[, headers[, body]]);           

destination url 為伺服器 controller中 @MessageMapping 中比對的URL,字元串,必須參數;

headers 為發送資訊的header,JavaScript 對象,可選參數;

body 為發送資訊的 body,字元串,可選參數;

例:

client.send("/queue/test", {priority: 9}, "Hello, STOMP");
client.send("/queue/test", {}, "Hello, STOMP");           

訂閱、接收資訊

STOMP 用戶端要想接收來自伺服器推送的消息,必須先訂閱相應的URL,即發送一個 SUBSCRIBE 幀,然後才能不斷接收來自伺服器的推送消息;

訂閱和接收消息通過 subscribe() 方法實作:

subscribe(destination url, callback[, headers])           

destination url 為伺服器 @SendTo 比對的 URL,字元串;

callback 為每次收到伺服器推送的消息時的回調方法,該方法包含參數 message;

headers 為附加的headers,JavaScript 對象;什麼作用?

該方法傳回一個包含了id屬性的 JavaScript 對象,可作為 unsubscribe() 方法的參數;

var headers = {ack: 'client', 'selector': "location = 'Europe'"};
var  callback = function(message) {
  if (message.body) {
    alert("got message with body " + message.body)
  } else {
    alert("got empty message");
  }
});
var subscription = client.subscribe("/queue/test", callback, headers);           

取消訂閱

var subscription = client.subscribe(...);

subscription.unsubscribe();           

JSON 支援

STOMP 幀的 body 必須是 string 類型,若希望接收/發送 json 對象,可通過 JSON.stringify() and JSON.parse() 實作;

例:

var quote = {symbol: 'APPL', value: 195.46};
client.send("/topic/stocks", {}, JSON.stringify(quote));

client.subcribe("/topic/stocks", function(message) {
var quote = JSON.parse(message.body);
alert(quote.symbol + " is at " + quote.value);
});           

事務支援

STOMP 用戶端支援在發送消息時用事務進行處理:

舉例說明:

// start the transaction
// 該方法傳回一個包含了事務 id、commit()、abort() 的JavaScript 對象
var tx = client.begin();
// send the message in a transaction
// 最關鍵的在于要在 headers 對象中加入事務 id,若沒有添加,則會直接發送消息,不會以事務進行處理
client.send("/queue/test", {transaction: tx.id}, "message in a transaction");
// commit the transaction to effectively send the message
tx.commit();
// tx.abort();           

Debug 資訊

STOMP 用戶端預設将傳輸過程中的所有 debug 資訊以 console.log() 形式輸出到用戶端浏覽器中,也可通過以下方式輸出到 DOM 中:

client.debug = function(str) {
    // str 參數即為 debug 資訊
// append the debug log to a #debug div somewhere in the page using JQuery:
$("#debug").append(str + "\n");
};           

認證

這一部分内容看的不是很了解,是以直接将原文放在這裡了,待補充。

By default, STOMP messages will be automatically acknowledged by the server before the message is delivered to the client.

var subscription = client.subscribe("/queue/test",
  function(message) {
    // do something with the message
    ...
    // and acknowledge it
    message.ack();
  },
  {ack: 'client'}
);           

繼續閱讀