STOMP即Simple (or Streaming) Text Orientated Messaging Protocol,簡單(流)文本定向消息協議,它提供了一個可互操做的鏈接格式,容許STOMP客戶端與任意STOMP消息代理(Broker)進行交互。STOMP協議因爲設計簡單,易於開發客戶端,所以在多種語言和多種平臺上獲得普遍地應用。javascript
1、建立STOMP
客戶端java
一、在web瀏覽器中使用普通的Web Socketnode
STOMP javascript 客戶端會使用ws://
的URL與STOMP 服務端進行交互。web
爲了建立一個STOMP客戶端js對象,你須要使用Stomp.client(url)
,而這個URL鏈接着服務端的WebSocket的代理npm
var url = "ws://localhost:61614/stomp"; var client = Stomp.client(url);
Stomp.client(url, protocols)
也能夠用來覆蓋默認的subprotocols
。第二個參數能夠是一個字符串或一個字符串數組去指定多個subprotocols
。數組
二、在web瀏覽器中使用定製的WebSocket瀏覽器
瀏覽器提供了不一樣的WebSocket的協議,一些老的瀏覽器不支持WebSocket的腳本或者使用別的名字。默認下,stomp.js
會使用瀏覽器原生的WebSocket class
去建立WebSocket。併發
可是利用Stomp.over(ws)
這個方法可使用其餘類型的WebSockets。這個方法獲得一個知足WebSocket定義的對象。app
例如,可使用由SockJS
實現的Websocket。異步
若是使用原生的Websockets就使用Stomp.client(url)
,若是須要使用其餘類型的Websocket(例如由SockJS包裝的Websocket)就使用Stomp.over(ws)
。除了初始化有差異,Stomp API在這兩種方式下是相同的。
三、在node.js
程序中
經過stompjs npm package
一樣也能夠在node.js
程序中使用這個庫。
npm install stompjs
在node.js app
中,require
這個模塊:var Stomp = require('stompjs');
爲了與創建在TCP socket的STOMP-broker鏈接,使用Stomp.overTCP(host, port)
方法。
var client = Stomp.overTCP('localhost', 61613);
爲了與創建在Web Socket的STOMP broker鏈接,使用Stomp.overWS(url)
方法。
var client = Stomp.overWS('ws://localhost:61614/stomp');
除了初始化不一樣,不管是瀏覽器仍是node.js環境下,Stomp API都是相同的。
2、連接服務端
一旦Stomp 客戶端創建了,必須調用它的connect()
方法去鏈接Stomp服務端進行驗證。這個方法須要兩個參數,用戶的登陸和密碼憑證。這種狀況下,客戶端會使用Websocket打開鏈接,併發送一個CONNECT frame
。
這個鏈接是異步進行的:你不能保證當這個方法返回時是有效鏈接的。爲了知道鏈接的結果,你須要一個回調函數。
var connect_callback = function() { // called back after the client is connected and authenticated to the STOMP server
};
可是若是鏈接失敗會發生什麼呢?
connect()
方法接受一個可選的參數(error_callback
),當客戶端不能鏈接上服務端時,這個回調函數error_callback
會被調用,該函數的參數爲對應的錯誤對象。
var error_callback = function(error) { // display the error's message header:
alert(error.headers.message); };
在大多數狀況下,connect()
方法可接受不一樣數量的參數來提供簡單的API:
client.connect(login, passcode, connectCallback);
client.connect(login, passcode, connectCallback, errorCallback);
client.connect(login, passcode, connectCallback, errorCallback, host);
login
和passcode
是strings,connectCallback
和errorCallback
則是functions。(有些brokers(代理)還須要傳遞一個host
(String類型)參數。)
若是你須要附加一個headers
頭部,connect
方法還接受其餘兩種形式的參數:
client.connect(headers, connectCallback);
client.connect(headers, connectCallback, errorCallback);
header
是map
形式,connectCallback
和errorCallback
爲functions。
須要注意:若是你使用上述這種方式,你須要自行在headers
添加login
、passcode
(甚至host
):
var headers = { login: 'mylogin', passcode: 'mypasscode', // additional header
'client-id': 'my-client-id' }; client.connect(headers, connectCallback);
斷開鏈接時,調用disconnect
方法,這個方法也是異步的,當斷開成功後會接收一個額外的回調函數的參數。以下所示。
client.disconnect(function() { alert("See you next time!"); };
當客戶端與服務端斷開鏈接,就不會再發送或接收消息了。
3、Heart-beating
若是STOMP broker(代理)接收STOMP 1.1版本的幀,heart-beating
是默認啓用的。
heart-beating
也就是頻率,incoming
是接收頻率,outgoing
是發送頻率。經過改變incoming
和outgoing
能夠更改客戶端的heart-beating
(默認爲10000ms):
client.heartbeat.outgoing = 20000; // client will send heartbeats every 20000ms
client.heartbeat.incoming = 0; // client does not want to receive heartbeats // from the server
heart-beating
是利用window.setInterval()
去規律地發送heart-beats
或者檢查服務端的heart-beats
。
4、發送消息
當客戶端與服務端鏈接成功後,能夠調用send()
來發送STOMP消息。這個方法必須有一個參數,用來描述對應的STOMP的目的地。另外能夠有兩個可選的參數:headers
,object
類型包含額外的信息頭部;body
,一個String類型的參數。
client.send("/queue/test", {priority: 9}, "Hello, STOMP"); // client會發送一個STOMP發送幀給/queue/test,這個幀包含一個設置了priority爲9的header和內容爲「Hello, STOMP」的body。
client.send(destination, {}, body);
若是你想發送一個有body
的信息,也必須傳遞headers
參數。若是沒有headers
須要傳遞,那麼就傳{}
便可。
5、訂閱(Subscribe)和接收(receive)消息
爲了在瀏覽器中接收消息,STOMP客戶端必須先訂閱一個目的地destination
。
你可使用subscribe()
去訂閱。這個方法有2個必需的參數:目的地(destination
),回調函數(callback
);還有一個可選的參數headers
。其中destination
是String類型,對應目的地,回調函數是伴隨着一個參數的function
類型。
var subscription = client.subscribe("/queue/test", callback);
subscribe()
方法返回一個object
,這個object
包含一個id
屬性,對應這個這個客戶端的訂閱ID。
而unsubscribe()
能夠用來取消客戶端對這個目的地destination
的訂閱。
默認狀況下,若是沒有在headers
額外添加,這個庫會默認構建一個獨一無二的ID
。在傳遞headers
這個參數時,可使用你本身的ID
。
var mysubid = '...'; var subscription = client.subscribe(destination, callback, { id: mysubid });
這個客戶端會向服務端發送一個STOMP訂閱幀(SUBSCRIBE frame
)並註冊回調事件。每次服務端向客戶端發送消息時,客戶端都會輪流調用回調函數,參數爲對應消息的STOMP幀對象(Frame object
)。
subscribe()
方法,接受一個可選的headers
參數用來標識附加的頭部。
var headers = {ack: 'client', 'selector': "location = 'Europe'"}; client.subscribe("/queue/test", message_callback, headers);
這個客戶端指定了它會確認接收的信息,只接收符合這個selector : location = 'Europe'
的消息。
若是想讓客戶端訂閱多個目的地,你能夠在接收全部信息的時候調用相同的回調函數:
onmessage = function(message) { // called every time the client receives a message
} var sub1 = client.subscribe("queue/test", onmessage); var sub2 = client.subscribe("queue/another", onmessage)
若是要停止接收消息,客戶端能夠在subscribe()
返回的object
對象調用unsubscribe()
來結束接收。
var subscription = client.subscribe(...); ... subscription.unsubscribe();
6、支持JSON
STOMP消息的body
必須爲字符串。若是你須要發送/接收JSON
對象,你可使用JSON.stringify()
和JSON.parse()
去轉換JSON對象。
7、Acknowledgment(確認)
默認狀況,在消息發送給客戶端以前,服務端會自動確認(acknowledged
)。
客戶端能夠選擇經過訂閱一個目的地時設置一個ack header
爲client
或client-individual
來處理消息確認。
在下面這個例子,客戶端必須調用message.ack()
來通知服務端它已經接收了消息。
var subscription = client.subscribe("/queue/test", function(message) { // do something with the message
... // and acknowledge it
message.ack(); }, {ack: 'client'} );
ack()
接受headers
參數用來附加確認消息。例如,將消息做爲事務(transaction)的一部分,當要求接收消息時其實代理(broker)已經將ACK STOMP frame
處理了。
var tx = client.begin(); message.ack({ transaction: tx.id, receipt: 'my-receipt' }); tx.commit();
nack()
也能夠用來通知STOMP 1.1.brokers(代理):客戶端不能消費這個消息。與ack()
方法的參數相同。
8、事務(Transactions)
能夠在將消息的發送和確認接收放在一個事務中。
客戶端調用自身的begin()
方法就能夠開始啓動事務了,begin()
有一個可選的參數transaction
,一個惟一的可標識事務的字符串。若是沒有傳遞這個參數,那麼庫會自動構建一個。這個方法會返回一個object。這個對象有一個id
屬性對應這個事務的ID,還有兩個方法:
commit()
提交事務
abort()
停止事務
在一個事務中,客戶端能夠在發送/接受消息時指定transaction id來設置transaction。
// start the transaction
var tx = client.begin(); // send the message in a transaction
client.send("/queue/test", {transaction: tx.id}, "message in a transaction"); // commit the transaction to effectively send the message
tx.commit();
若是你在調用send()
方法發送消息的時候忘記添加transction header,那麼這不會稱爲事務的一部分,這個消息會直接發送,不會等到事務完成後才發送。
var txid = "unique_transaction_identifier"; // start the transaction
var tx = client.begin(); // oops! send the message outside the transaction
client.send("/queue/test", {}, "I thought I was in a transaction!"); tx.abort(); // Too late! the message has been sent
9、調試
有一些測試代碼能有助於你知道庫發送或接收的是什麼,從而來調試程序。
客戶端能夠將其debug
屬性設置爲一個函數,傳遞一個字符串參數去觀察庫全部的debug語句。默認狀況,debug消息會被記錄在在瀏覽器的控制檯。
client.debug = function(str) { // append the debug log to a #debug div somewhere in the page using JQuery:
$("#debug").append(str + "\n"); };
10、使用狀況
一、var error_callback = function(error) {
第一次鏈接失敗和鏈接後斷開鏈接都會調用這個函數
};
二、關閉控制檯調試數據:設置client.debug = null
就能夠,stompjs會去檢測debug是不是函數,不是函數就不會調用輸出