原創 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'}
);