2014-12-11 07:17:29 -05:00
|
|
|
# Interoperability
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
## Stomp
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
[Stomp](http://stomp.github.com/) is a text-orientated wire protocol
|
|
|
|
that allows Stomp clients to communicate with Stomp Brokers. ActiveMQ
|
|
|
|
now supports Stomp 1.0, 1.1 and 1.2.
|
|
|
|
|
|
|
|
Stomp clients are available for several languages and platforms making
|
|
|
|
it a good choice for interoperability.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
## Native Stomp support
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
ActiveMQ provides native support for Stomp. To be able to send and
|
|
|
|
receive Stomp messages, you must configure a `NettyAcceptor` with a
|
|
|
|
`protocols` parameter set to have `stomp`:
|
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
<acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP</acceptor>
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
With this configuration, ActiveMQ will accept Stomp connections on the
|
|
|
|
port `61613` (which is the default port of the Stomp brokers).
|
|
|
|
|
|
|
|
See the `stomp` example which shows how to configure a ActiveMQ server
|
|
|
|
with Stomp.
|
|
|
|
|
|
|
|
### Limitations
|
|
|
|
|
|
|
|
Message acknowledgements are not transactional. The ACK frame can not be
|
|
|
|
part of a transaction (it will be ignored if its `transaction` header is
|
|
|
|
set).
|
|
|
|
|
|
|
|
### Stomp 1.1/1.2 Notes
|
|
|
|
|
|
|
|
#### Virtual Hosting
|
|
|
|
|
|
|
|
ActiveMQ currently doesn't support virtual hosting, which means the
|
|
|
|
'host' header in CONNECT fram will be ignored.
|
|
|
|
|
|
|
|
#### Heart-beating
|
|
|
|
|
|
|
|
ActiveMQ specifies a minimum value for both client and server heart-beat
|
|
|
|
intervals. The minimum interval for both client and server heartbeats is
|
|
|
|
500 milliseconds. That means if a client sends a CONNECT frame with
|
|
|
|
heartbeat values lower than 500, the server will defaults the value to
|
|
|
|
500 milliseconds regardless the values of the 'heart-beat' header in the
|
|
|
|
frame.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### Mapping Stomp destinations to ActiveMQ addresses and queues
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
Stomp clients deals with *destinations* when sending messages and
|
|
|
|
subscribing. Destination names are simply strings which are mapped to
|
|
|
|
some form of destination on the server - how the server translates these
|
|
|
|
is left to the server implementation.
|
|
|
|
|
|
|
|
In ActiveMQ, these destinations are mapped to *addresses* and *queues*.
|
|
|
|
When a Stomp client sends a message (using a `SEND` frame), the
|
|
|
|
specified destination is mapped to an address. When a Stomp client
|
|
|
|
subscribes (or unsubscribes) for a destination (using a `SUBSCRIBE` or
|
|
|
|
`UNSUBSCRIBE` frame), the destination is mapped to a ActiveMQ queue.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### STOMP and connection-ttl
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
Well behaved STOMP clients will always send a DISCONNECT frame before
|
|
|
|
closing their connections. In this case the server will clear up any
|
|
|
|
server side resources such as sessions and consumers synchronously.
|
|
|
|
However if STOMP clients exit without sending a DISCONNECT frame or if
|
|
|
|
they crash the server will have no way of knowing immediately whether
|
|
|
|
the client is still alive or not. STOMP connections therefore default to
|
|
|
|
a connection-ttl value of 1 minute (see chapter on
|
|
|
|
[connection-ttl](#connection-ttl) for more information. This value can
|
|
|
|
be overridden using connection-ttl-override.
|
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
If you need a specific connectionTtl for your stomp connections without
|
|
|
|
affecting the connectionTtlOverride setting, you can configure your
|
|
|
|
stomp acceptor with the "connectionTtl" property, which is used to set
|
2014-12-04 10:25:29 -05:00
|
|
|
the ttl for connections that are created from that acceptor. For
|
|
|
|
example:
|
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
<acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;connectionTtl=20000</acceptor>
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
The above configuration will make sure that any stomp connection that is
|
|
|
|
created from that acceptor will have its connection-ttl set to 20
|
|
|
|
seconds.
|
|
|
|
|
|
|
|
> **Note**
|
|
|
|
>
|
|
|
|
> Please note that the STOMP protocol version 1.0 does not contain any
|
|
|
|
> heartbeat frame. It is therefore the user's responsibility to make
|
|
|
|
> sure data is sent within connection-ttl or the server will assume the
|
|
|
|
> client is dead and clean up server side resources. With `Stomp 1.1`
|
|
|
|
> users can use heart-beats to maintain the life cycle of stomp
|
|
|
|
> connections.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### Stomp and JMS interoperability
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
#### Using JMS destinations
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
As explained in [Mapping JMS Concepts to the Core API](jms-core-mapping.md),
|
|
|
|
JMS destinations are also mapped to ActiveMQ
|
2014-12-04 10:25:29 -05:00
|
|
|
addresses and queues. If you want to use Stomp to send messages to JMS
|
|
|
|
destinations, the Stomp destinations must follow the same convention:
|
|
|
|
|
|
|
|
- send or subscribe to a JMS *Queue* by prepending the queue name by
|
|
|
|
`jms.queue.`.
|
|
|
|
|
|
|
|
For example, to send a message to the `orders` JMS Queue, the Stomp
|
|
|
|
client must send the frame:
|
|
|
|
|
|
|
|
SEND
|
|
|
|
destination:jms.queue.orders
|
|
|
|
|
|
|
|
hello queue orders
|
|
|
|
^@
|
|
|
|
|
|
|
|
- send or subscribe to a JMS *Topic* by prepending the topic name by
|
|
|
|
`jms.topic.`.
|
|
|
|
|
|
|
|
For example to subscribe to the `stocks` JMS Topic, the Stomp client
|
|
|
|
must send the frame:
|
|
|
|
|
|
|
|
SUBSCRIBE
|
|
|
|
destination:jms.topic.stocks
|
|
|
|
|
|
|
|
^@
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
#### Sending and consuming Stomp message from JMS or ActiveMQ Core API
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
Stomp is mainly a text-orientated protocol. To make it simpler to
|
|
|
|
interoperate with JMS and ActiveMQ Core API, our Stomp implementation
|
|
|
|
checks for presence of the `content-length` header to decide how to map
|
|
|
|
a Stomp message to a JMS Message or a Core message.
|
|
|
|
|
|
|
|
If the Stomp message does *not* have a `content-length` header, it will
|
|
|
|
be mapped to a JMS *TextMessage* or a Core message with a *single
|
|
|
|
nullable SimpleString in the body buffer*.
|
|
|
|
|
|
|
|
Alternatively, if the Stomp message *has* a `content-length` header, it
|
|
|
|
will be mapped to a JMS *BytesMessage* or a Core message with a *byte[]
|
|
|
|
in the body buffer*.
|
|
|
|
|
|
|
|
The same logic applies when mapping a JMS message or a Core message to
|
|
|
|
Stomp. A Stomp client can check the presence of the `content-length`
|
|
|
|
header to determine the type of the message body (String or bytes).
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
#### Message IDs for Stomp messages
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
When receiving Stomp messages via a JMS consumer or a QueueBrowser, the
|
|
|
|
messages have no properties like JMSMessageID by default. However this
|
|
|
|
may bring some inconvenience to clients who wants an ID for their
|
|
|
|
purpose. ActiveMQ Stomp provides a parameter to enable message ID on
|
|
|
|
each incoming Stomp message. If you want each Stomp message to have a
|
2015-02-23 04:50:08 -05:00
|
|
|
unique ID, just set the `stompEnableMessageId` to true. For example:
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
<acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;stompEnableMessageId=true</acceptor>
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
When the server starts with the above setting, each stomp message sent
|
|
|
|
through this acceptor will have an extra property added. The property
|
|
|
|
key is `
|
|
|
|
hq-message-id` and the value is a String representation of a
|
|
|
|
long type internal message id prefixed with "`STOMP`", like:
|
|
|
|
|
|
|
|
hq-message-id : STOMP12345
|
|
|
|
|
|
|
|
If `stomp-enable-message-id` is not specified in the configuration,
|
|
|
|
default is `false`.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
#### Handling of Large Messages with Stomp
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
Stomp clients may send very large bodys of frames which can exceed the
|
|
|
|
size of ActiveMQ server's internal buffer, causing unexpected errors. To
|
|
|
|
prevent this situation from happening, ActiveMQ provides a stomp
|
2015-02-23 04:50:08 -05:00
|
|
|
configuration attribute `stompMinLargeMessageSize`. This attribute
|
2014-12-04 10:25:29 -05:00
|
|
|
can be configured inside a stomp acceptor, as a parameter. For example:
|
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
<acceptor name="stomp-acceptor">tcp://localhost:61613?protocols=STOMP;stompMinLargeMessageSize=10240</acceptor>
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
The type of this attribute is integer. When this attributed is
|
|
|
|
configured, ActiveMQ server will check the size of the body of each
|
|
|
|
Stomp frame arrived from connections established with this acceptor. If
|
|
|
|
the size of the body is equal or greater than the value of
|
2015-02-23 04:50:08 -05:00
|
|
|
`stompMinLargeMessageSize`, the message will be persisted as a large
|
2014-12-04 10:25:29 -05:00
|
|
|
message. When a large message is delievered to a stomp consumer, the
|
|
|
|
HorentQ server will automatically handle the conversion from a large
|
|
|
|
message to a normal message, before sending it to the client.
|
|
|
|
|
|
|
|
If a large message is compressed, the server will uncompressed it before
|
|
|
|
sending it to stomp clients. The default value of
|
2015-02-23 04:50:08 -05:00
|
|
|
`stompMinLargeMessageSize` is the same as the default value of
|
2014-12-04 10:25:29 -05:00
|
|
|
[min-large-message-size](#large-messages.core.config).
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### Stomp Over Web Sockets
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
ActiveMQ also support Stomp over [Web
|
|
|
|
Sockets](http://dev.w3.org/html5/websockets/). Modern web browser which
|
|
|
|
support Web Sockets can send and receive Stomp messages from ActiveMQ.
|
|
|
|
|
|
|
|
To enable Stomp over Web Sockets, you must configure a `NettyAcceptor`
|
|
|
|
with a `protocol` parameter set to `stomp_ws`:
|
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
<acceptor name="stomp-ws-acceptor">tcp://localhost:61614?protocols=STOMP_WS</acceptor>
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
With this configuration, ActiveMQ will accept Stomp connections over Web
|
|
|
|
Sockets on the port `61614` with the URL path `/stomp`. Web browser can
|
|
|
|
then connect to `ws://<server>:61614/stomp` using a Web Socket to send
|
|
|
|
and receive Stomp messages.
|
|
|
|
|
|
|
|
A companion JavaScript library to ease client-side development is
|
|
|
|
available from [GitHub](http://github.com/jmesnil/stomp-websocket)
|
|
|
|
(please see its [documentation](http://jmesnil.net/stomp-websocket/doc/)
|
|
|
|
for a complete description).
|
|
|
|
|
|
|
|
The `stomp-websockets` example shows how to configure ActiveMQ server to
|
|
|
|
have web browsers and Java applications exchanges messages on a JMS
|
|
|
|
topic.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### StompConnect
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
[StompConnect](http://stomp.codehaus.org/StompConnect) is a server that
|
|
|
|
can act as a Stomp broker and proxy the Stomp protocol to the standard
|
|
|
|
JMS API. Consequently, using StompConnect it is possible to turn
|
|
|
|
ActiveMQ into a Stomp Broker and use any of the available stomp clients.
|
|
|
|
These include clients written in C, C++, c\# and .net etc.
|
|
|
|
|
|
|
|
To run StompConnect first start the ActiveMQ server and make sure that
|
|
|
|
it is using JNDI.
|
|
|
|
|
|
|
|
Stomp requires the file `jndi.properties` to be available on the
|
|
|
|
classpath. This should look something like:
|
|
|
|
|
|
|
|
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
|
|
|
|
|
|
|
|
Configure any required JNDI resources in this file according to the
|
|
|
|
documentation.
|
|
|
|
|
|
|
|
Make sure this file is in the classpath along with the StompConnect jar
|
|
|
|
and the ActiveMQ jars and simply run `java org.codehaus.stomp.jms.Main`.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
## REST
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
Please see [Rest Interface](rest.md)
|
2014-12-04 10:25:29 -05:00
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
## AMQP
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
ActiveMQ supports the [AMQP
|
|
|
|
1.0](https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=amqp)
|
|
|
|
specification. To enable AMQP you must configure a Netty Acceptor to
|
|
|
|
receive AMQP clients, like so:
|
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
<acceptor name="stomp-acceptor">tcp://localhost:5672?protocols=AMQP</acceptor>
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
ActiveMQ will then accept AMQP 1.0 clients on port 5672 which is the
|
|
|
|
default AMQP port.
|
|
|
|
|
|
|
|
There are 2 Stomp examples available see proton-j and proton-ruby which
|
|
|
|
use the qpid Java and Ruby clients respectively
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### AMQP and security
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
The ActiveMQ Server accepts AMQP SASL Authentication and will use this
|
|
|
|
to map onto the underlying session created for the connection so you can
|
|
|
|
use the normal ActiveMQ security configuration.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### AMQP Links
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
An AMQP Link is a uni directional transport for messages between a
|
|
|
|
source and a target, i.e. a client and the ActiveMQ Broker. A link will
|
|
|
|
have an endpoint of which there are 2 kinds, a Sender and A Receiver. At
|
|
|
|
the Broker a Sender will have its messages converted into a ActiveMQ
|
|
|
|
Message and forwarded to its destination or target. A Receiver will map
|
|
|
|
onto a ActiveMQ Server Consumer and convert ActiveMQ messages back into
|
|
|
|
AMQP messages before being delivered.
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### AMQP and destinations
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
If an AMQP Link is dynamic then a temporary queue will be created and
|
|
|
|
either the remote source or remote target address will be set to the
|
|
|
|
name of the temporary queue. If the Link is not dynamic then the the
|
|
|
|
address of the remote target or source will used for the queue. If this
|
|
|
|
does not exist then an exception will be sent
|
|
|
|
|
|
|
|
> **Note**
|
|
|
|
>
|
|
|
|
> For the next version we will add a flag to aut create durable queue
|
|
|
|
> but for now you will have to add them via the configuration
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
### AMQP and Coordinations - Handling Transactions
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
An AMQP links target can also be a Coordinator, the Coordinator is used
|
|
|
|
to handle transactions. If a coordinator is used the the underlying
|
|
|
|
HormetQ Server session will be transacted and will be either rolled back
|
|
|
|
or committed via the coordinator.
|
|
|
|
|
|
|
|
> **Note**
|
|
|
|
>
|
|
|
|
> AMQP allows the use of multiple transactions per session,
|
|
|
|
> `amqp:multi-txns-per-ssn`, however in this version ActiveMQ will only
|
|
|
|
> support single transactions per session
|
|
|
|
|
2014-12-11 07:17:29 -05:00
|
|
|
## OpenWire
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
ActiveMQ now supports the
|
|
|
|
[OpenWire](http://activemq.apache.org/openwire.html) protocol so that an
|
|
|
|
ActiveMQ JMS client can talk directly to a ActiveMQ server. To enable
|
|
|
|
OpenWire support you must configure a Netty Acceptor, like so:
|
|
|
|
|
2015-02-23 04:50:08 -05:00
|
|
|
<acceptor name="openwire-acceptor">tcp://localhost:61616?protocols=OPENWIRE</acceptor>
|
2014-12-04 10:25:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
The ActiveMQ server will then listens on port 61616 for incoming
|
|
|
|
openwire commands. Please note the "protocols" is not mandatory here.
|
|
|
|
The openwire configuration conforms to ActiveMQ's "Single Port" feature.
|
|
|
|
Please refer to [Configuring Single
|
|
|
|
Port](#configuring-transports.single-port) for details.
|
|
|
|
|
|
|
|
Please refer to the openwire example for more coding details.
|
|
|
|
|
|
|
|
Currently we support ActiveMQ clients that using standard JMS APIs. In
|
|
|
|
the future we will get more supports for some advanced, ActiveMQ
|
|
|
|
specific features into ActiveMQ.
|