STOMP是一种简单的面向文本的消息传递协议。它定义了一种可互操作的有线格式, 以便任何可用的STOMP客户端都可以与任何STOMP消息代理进行通信,以在各种语言和平台之间提供简单而广泛的消息互操作性(STOMP网站上有STOMP客户端和服务器实现的列表。
WebSockets是“用于Web的TCP”。
当Google宣布在Chrome浏览器中提供 WebSocket时,它解释了WebSockets背后的想法:
WebSocket API使Web应用程序能够以直接的方式处理与服务器端进程的双向通信。开发人员已经将XMLHttpRequest(“ XHR”)用于此类目的,但是XHR使开发与服务器进行来回通信的Web应用程序变得不必要地复杂。XHR基本上是异步HTTP,并且由于您需要使用诸如长期悬挂的GET这样的棘手技术来将数据从服务器发送到浏览器,因此简单的任务会迅速变得复杂。与XMLHttpRequest相反,WebSockets在您的浏览器中提供了一个真正的双向通信通道。一旦获得WebSocket连接,就可以通过调用send()方法从浏览器向服务器发送数据,并通过onmessage事件处理程序从服务器向浏览器接收数据。
除了新的WebSocket API外,浏览器还用于与服务器进行通信的新协议(“ WebSocket协议”)。该协议不是原始TCP,因为它需要提供浏览器的“同源”安全模型。它也不是HTTP,因为WebSocket流量不同于HTTP的请求-响应模型。使用新的WebSocket协议的WebSocket通信应使用较少的带宽,因为与一系列XHR和悬挂的GET不同,一旦建立了单个连接,就不会交换任何标头。要使用此新的API和协议并利用更简单的编程模型和更有效的网络流量,您确实需要与之通信的新服务器实现。
该API是HTML5的一部分,并且大多数现代Web浏览器(包括Mac OS X和iOS上的Google Chrome,Firefox和Safari)都支持(不同程度...)。
该库支持多种版本的STOMP协议:
该库不是纯STOMP客户端。它旨在在非TCP的WebSockets协议上运行。基本上,WebSocket协议要求浏览器的客户端和服务器之间进行握手,以确保浏览器的“同源”安全模型保持有效。
这意味着该库无法连接到常规STOMP代理,因为它们不了解由WebSocket发起的握手,该握手不是STOMP协议的一部分,并且可能会拒绝连接。
目前正在进行将WebSocket支持添加到STOMP代理的工作,以便他们将通过WebSocket协议接受STOMP连接。
HornetQ是Red Hat和JBoss开发的开源消息传递系统。
要使用支持通过WebSocket的STOMP来启动HornetQ,请下载最新版本并运行以下步骤:
$ cd hornetq-x.y.z/examples/jms/stomp-websockets$ mvn clean install... INFO:HQ221020:启动了Netty Acceptor版本3.6.2,用于STOMP_WS协议的Final-c0d783c localhost:61614 2013年4月15日,下午1:15:33 org.hornetq.core.server.impl.HornetQServerImpl $ SharedStoreLiveActivation运行 INFO:HQ221007:服务器现在处于活动状态 2013年4月15日,下午1:15:33 org.hornetq.core.server.impl.HornetQServerImpl开始 信息:HQ221001:HornetQ Server版本2.3.0.CR2(black‘n‘yellow2,123)[c9e29e45-a5bd-11e2-976a-b3fef7ceb5df]
HornetQ现在已启动,并通过端口上的WebSocket监听STOMP 61614。
它接受来自URL的WebSocket连接ws://localhost:61614/stomp
要在启用了STOMP Over WebSocket的情况下配置和运行HornetQ,请按照 说明进行操作。
ActiveMQ是Apache开发的开源消息传递系统。从5.4快照开始,ActiveMQ支持STOMP Over WebSocket。
要在启用了STOMP Over WebSocket的情况下配置和运行ActiveMQ,请按照 说明进行操作。
ActiveMQ Apollo是下一代ActiveMQ代理。从一开始,Apollo就支持STOMP Over WebSocket。
要在启用了STOMP Over WebSocket的情况下配置和运行Apollo,请按照 说明进行操作。
RabbitMQ是VMware赞助的开源消息传递系统。
要在启用了STOMP Over WebSocket的情况下配置和运行RabbitMQ,请按照说明安装Web-Stomp插件。
Stilts是一个STOMP本地消息传递框架,旨在解决将STOMP视为消息传递的主要合同,并围绕它进行集成,而不是简单地将STOMP填充应用于现有服务。
TorqueBox使用Stilts项目提供其WebSockets和STOMP堆栈。
您可以下载stomp.js以便在您的Web应用程序中使用它
一个精缩版,还提供了生产中使用。
该JavaScript文件是从CoffeeScript文件生成的。请参阅“贡献”部分以下载源代码或浏览带注释的源代码。
WebSocket上的STOMP提供了从STOMP框架到JavaScript对象的直接映射。
| 财产 | 类型 | 笔记 | 
|---|---|---|
command | 
细绳 | 该帧的名称("CONNECT","SEND"等) | 
headers | 
JavaScript对象 | |
body | 
细绳 | 
的command和headers特性将总是被限定,但headers如果该帧不具有报头可以是空的。该body可null如果框架没有一个机构。
STOMP JavaScript客户端将使用ws://URL与STOMP服务器进行通信。
要创建STOMP客户端JavaScript对象,您需要Stomp.client(url) 使用与服务器的WebSocket端点相对应的URL进行调用:
  var url = "ws://localhost:61614/stomp";
  var client = Stomp.client(url);
的Stomp.client(url, protocols)也可用于覆盖由库提供的默认子协议:[‘v10.stomp‘, ‘v11.stomp]‘(对于STOMP 1.0 1.1规范)。第二个参数可以是单个字符串,也可以是字符串数组,以指定多个子协议。
Web浏览器支持WebSocket协议的不同版本。一些较旧的浏览器不提供WebSocket JavaScript或以其他名称公开它。默认情况下,stomp.js将使用Web浏览器本机WebSocket类创建WebSocket。
但是,可以通过使用该Stomp.over(ws)方法来使用其他类型的WebSocket 。此方法需要一个符合WebSocket定义的对象。
例如,可以使用SockJS项目提供的实现,而该实现可以使用各种特定于浏览器的传输协议来代替:
  <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
  <script>
    // use SockJS implementation instead of the browser‘s native implementation
    var ws = new SockJS(url);
    var client = Stomp.over(ws);
    [...]
  </script>
使用Stomp.client(url)使用普通的WebSockets或使用Stomp.over(ws),如果你需要另一种类型的WebSocket的。
除了此初始化之外,两种情况下的STOMP API均相同。
通过使用stompjs npm包,该库也可以在node.js应用程序中使用 。
$ npm install stompjs
在node.js应用程序中,要求模块具有:
  var Stomp = require(‘stompjs‘);
要通过TCP套接字连接到STOMP代理,请使用以下Stomp.overTCP(host, port)方法:
  var client = Stomp.overTCP(‘localhost‘, 61613);
要通过Web Socket连接到STOMP代理,请改用以下Stomp.overWS(url)方法:
  var client = Stomp.overWS(‘ws://localhost:61614/stomp‘);
除了此初始化之外,无论STOMP API是在Web浏览器中还是在node.js应用程序中运行,都保持不变。
创建STOMP客户端后,它必须调用其connect()方法以有效连接并验证STOMP服务器。该方法采用两个强制性参数, login并且passcode与用户凭据相对应。
在后台,客户端将使用WebSocket打开连接并发送CONNECT框架。
连接是异步完成的:您无法保证在调用connect返回时被有效连接。要通知连接,您需要将一个connect_callback函数传递 给connect()方法:
  var connect_callback = function() {
    // called back after the client is connected and authenticated to the STOMP server
  };
但是,如果连接失败怎么办?该connect()方法接受一个可选error_callback参数,如果客户端无法连接到服务器,则该参数将被调用。回调将使用单个参数调用,该参数是与STOMP ERROR帧相对应的错误对象 :
  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是字符串,connectCallback并且errorCallback是函数(某些代理还要求传递主机字符串)。
connect()如果您需要传递其他标头,则该方法还接受其他两个变体:
  client.connect(headers, connectCallback);
  client.connect(headers, connectCallback, errorCallback);
哪里header是地图,connectCallback并且errorCallback是函数。
请注意,如果您使用这些形式,则必须自己添加login,passcode(并最终添加host)标题:
    var headers = {
      login: ‘mylogin‘,
      passcode: ‘mypasscode‘,
      // additional header
      ‘client-id‘: ‘my-client-id‘
    };
    client.connect(headers, connectCallback);
  
要断开客户端与服务器的连接,可以调用其disconnect()方法。断开连接是异步的:断开连接有效时会收到通知,该disconnect方法采用可选callback参数。
  client.disconnect(function() {
    alert("See you next time!");
  };
客户端断开连接后,它将不再能够发送或接收消息。
如果STOMP代理接受STOMP 1.1帧,则默认情况下会启用心跳。
该client对象具有一个heartbeat字段,可通过更改其字段incoming和outgoing整数字段来配置心跳(两个字段的默认值为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
心跳window.setInterval()用于定期发送心跳和/或检查服务器心跳。
当客户端连接到服务器时,它可以使用该send()方法发送STOMP消息。该方法采用destination 与STOMP目的地相对应的强制性参数。它还具有两个可选参数:headers,一个包含其他消息头的JavaScript对象,和body一个String对象。
  client.send("/queue/test", {priority: 9}, "Hello, STOMP");
客户端将向目的地发送STOMP SEND帧/queue/test,其标头priority设置为9和正文Hello, STOMP。
如果要发送带有正文的消息,则还必须传递headers 参数。如果没有要传递的标头,请使用空的JavaScript文字{}:
  client.send(destination, {}, body);
  
要在浏览器中接收消息,STOMP客户端必须首先订阅目标。
您可以使用该subscribe()方法订阅目的地。该方法具有2个强制参数:destination,对应于目的地的String和 callback,具有一个message参数和可选参数的函数headers,用于附加标头的JavaScript对象。
  var subscription = client.subscribe("/queue/test", callback);
这些subscribe()方法返回一个具有1属性的JavaScript对象id,该属性与客户端订阅ID相对应,并且是一种unsubscribe()可以稍后用于从此目的地退订客户端的方法。
默认情况下,如果标头中未提供唯一的ID,则库将生成唯一的ID。要使用您自己的ID,请使用headers参数传递它:
  var mysubid = ‘...‘;
  var subscription = client.subscribe(destination, callback, { id: mysubid });
客户端将向服务器发送STOMP SUBSCRIBE帧并注册回调。每次服务器向客户端发送消息时,客户端将依次使用与消息相对应的STOMP Frame对象调用回调:
  callback = function(message) {
    // called when the client receives a STOMP message from the server
    if (message.body) {
      alert("got message with body " + message.body)
    } else {
      alert("got empty message");
    }
  });
订阅目标时,该subscribe()方法采用一个可选headers参数来指定其他标头:
  var headers = {ack: ‘client‘, ‘selector‘: "location = ‘Europe‘"};
  client.subscribe("/queue/test", message_callback, headers);
客户端指定它将处理消息确认,并且有兴趣仅接收与选择器匹配的消息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);
  
要停止接收消息,客户端可以在该unsubscribe()方法返回的对象上使用该subscribe() 方法。
  var subscription = client.subscribe(...);
  
  ...
  
  subscription.unsubscribe();
STOMP消息的正文必须为String。如果要发送和接收 JSON对象,则可以使用JSON.stringify()和JSON.parse()将JSON对象转换为String,反之亦然。
  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消息将在被传递到客户端之前由服务器自动确认。
客户端可以选择订阅目的地并选择设置为或的标头来处理消息确认。ackclientclient-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用于其他标头的参数以确认消息。例如,当ACK代理有效地处理了STOMP帧时,可以确认消息是交易的一部分,并要求收据:
  var tx = client.begin();
  message.ack({ transaction: tx.id, receipt: ‘my-receipt‘ });
  tx.commit();
该nack()方法也可以用于通知STOMP 1.1经纪人,客户端并不会消耗该消息。它采用与ack()方法相同的参数。
可以在事务中发送和确认消息。
事务由客户端使用其begin()方法来启动,该方法采用一个可选transaction的String来唯一标识该事务。如果没有transaction通过,该库将自动生成一个。
此方法返回一个JavaScript对象,该对象具有与id事务ID对应的属性和两个方法:
commit() 提交交易abort() 中止交易然后,客户端可以通过指定交易transaction集来发送和/或确认交易中的消息 id。
  // 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();
如果您transaction在调用时忘记添加标头,则send() 该消息将不属于事务,并且将直接发送,而无需等待事务完成。
  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
  
代码中几乎没有测试,这有助于查看从库发送和接收的内容以调试应用程序。
客户端可以将其debug属性设置为带有String参数的函数,以查看该库的所有调试语句:
  client.debug = function(str) {
    // append the debug log to a #debug div somewhere in the page using JQuery:
    $("#debug").append(str + "\n");
  };
默认情况下,调试消息记录在浏览器窗口的控制台中。
源代码中包含一个聊天示例 examples/chat/index.html
您需要启动一个支持WebSocket的STOMP服务器(例如使用HornetQ)。
单击Connect按钮以连接到服务器并订阅/queue/test/队列。
然后,您可以在页面底部的表单中键入消息,以将STOMP消息发送到队列。客户收到的消息将显示在页面顶部。
您还可以发送常规的STOMP消息,并在浏览器中看到它们。例如,直接telnet在STOMP默认端口上使用:
$ telnet localhost 61613 CONNECT login:guest passcode:guest ^@ 连接的 会话:1092296064
^@是一个空(control-@以ASCII为单位)字节。
SEND destination:/queue/test Hello from TCP! ^@
您现在应该已经在浏览器中收到此消息。
原文:https://www.cnblogs.com/bingying312/p/14591697.html