The following is an informal definition of WAMP - The WebSocket Application Messaging Protocol. The text describes version 1 of the protocol and should be sufficient for developers to create interoperable implementations. Specific features are subject to change in WAMP v2.
WAMP is based on established Web standards:
Though WAMP is currently defined with respect to above concrete standards, effectively it only makes the following assumptions.
Transport
A reliable, ordered, full-duplex message channel is assumed.
The default binding is WebSocket as Transport.
Serialization
A message payload serialization format is assumed that at least provides:
integers, strings and lists.
The default binding is JSON as Serialization.
IDs
An ID space that allows global assignment and resolution is assumed.
The default binding is URIs from the HTTP scheme as IDs
for both topics and procedures.
All messages are transmitted as WebSocket messages of payload type text, and hence UTF-8 encoded, with the payload being valid JSON.
WAMP defines the message types which are used in the communication between two WebSocket endpoints, the client and the server, and describes associated semantics.
WAMP is based on the following 9 message types:
| Message | Type ID | Direction | Category |
|---|---|---|---|
| WELCOME | 0 | Server-to-client | Auxiliary |
| PREFIX | 1 | Client-to-server | Auxiliary |
| CALL | 2 | Client-to-server | RPC |
| CALLRESULT | 3 | Server-to-client | RPC |
| CALLERROR | 4 | Server-to-client | RPC |
| SUBSCRIBE | 5 | Client-to-server | PubSub |
| UNSUBSCRIBE | 6 | Client-to-server | PubSub |
| PUBLISH | 7 | Client-to-server | PubSub |
| EVENT | 8 | Server-to-client | PubSub |
Write me.
The first server-to-client message sent by a WAMP server is always
With both messaging patterns, a client MAY use the following client-to-server message:
When a WAMP client connects to a WAMP server, the very first message sent by the server is always a
[ TYPE_ID_WELCOME , sessionId , protocolVersion, serverIdent ]
message. The sessionId is a string that is randomly generated by the server and unique to the specific WAMP session. The sessionId can be used for at least two situations: 1) specifying lists of excluded or eligible clients when publishing event and 2) in the context of performing authentication or authorization.
The protocolVersion is an integer that gives the WAMP protocol version the server speaks, currently it MUST be 1.
The serverIdent is a string the server may use to disclose it's version, software, platform or identity.
[0, "v59mbCGDXZ7WTyxB", 1, "Autobahn/0.5.1"]
Both procedures (and errors) in RPC and topics in PubSub are identified using URIs or CURIEs. Whenever a URI is used, full identification of the procedure/topic is provided by this URI. However, URIs can get long, which means tedious to input for developers, and also resulting in considerable volume on wire, when many small messages are exchanged.
To counter that, URIs MAY be abbreviated using the CURIE (Compact URI Expression) syntax. For example, the (full) URI:
may be abbreviated as
when it was previously agreed that the prefix calc is meant to stand for
To establish such agreement, a client sends a PREFIX message
[ TYPE_ID_PREFIX , prefix , URI ]
to the server.
[1, "calc", "http://example.com/simple/calc#"]
[1, "keyvalue", "http://example.com/simple/keyvalue#"]
The agreement is per-connection, and has a lifetime starting with the server receiving a PREFIX message establishing a prefix-to-URI mapping, and ending with the WebSocket connection.
The message is a JSON list consisting of TYPE_ID_PREFIX, the message type ID as an integer, followed by the prefix, a string to be used as prefix, followed by URI, the URI which is subsequently to be abbreviated using the prefix.
Both the prefix and the URI MUST follow the requirements as set forth in URIs or CURIEs
The Remote Procedure Call messaging pattern is realized with 3 messages:
A client initiates a RPC by sending a message
[ TYPE_ID_CALL , callID , procURI , ... ]
to the server.
The message is a JSON list consisting of TYPE_ID_CALL, the message type ID as an integer, followed by the callID, a string randomly generated by the client, followed by procURI, the URI of the remote procedure to be called, followed by zero or more call arguments.
The callID MUST be a randomly generated string. The callID is returned in CALLRESULT or CALLERROR by the server and used by the client to correlate the return message with the originating call.
The procURI is a string that identifies the remote procedure to be called and MUST be a valid URI or CURIE.
[2, "7DK6TdN4wLiUJgNM", "http://example.com/api#howdy"]
[2, "Yp9EFZt9DFkuKndg", "api:add2", 23, 99]
[2, "J5DkZJgByutvaDWc", "http://example.com/api#storeMeal",
{
"category": "dinner",
"calories": 2309
}]
[2, "Dns3wuQo0ipOX1Xc", "http://example.com/api#woooat", null]
[2, "M0nncaH0ywCSYzRv", "api:sum", [9, 1, 3, 4]]
[2, "ujL7WKGXCn8bkvFV", "keyvalue:set",
"foobar",
{
"value1": "23",
"value2": "singsing",
"value3": true,
"modified": "2012-03-29T10:29:16.625Z"
}]
When the execution of the remote procedure finishes, the server responds by sending a message of type CALLRESULT or CALLERROR.
The execution and sending is asynchronous, and there MAY be more than one RPC outstanding. An RPC is called outstanding (from the point of view of the client), when a result or error has not yet been received by the client.
When the execution of the remote procedure finishes successfully, the server responds by sending a
[ TYPE_ID_CALLRESULT , callID , result ]
to the client.
The message is a JSON list consisting of TYPE_ID_CALLRESULT, the message type ID as an integer, followed by the callID, the call correlation string that was randomly generated by the client, followed by result, the call result.
The result is always present and can be any JSON serializable value, include the JSON value null.
Examples
[3, "CcDnuI2bl2oLGBzO", null]
[3, "otZom9UsJhrnzvLa", "Awesome result .."]
[3, "CcDnuI2bl2oLGBzO",
{
"value3": true,
"value2": "singsing",
"value1": "23",
"modified": "2012-03-29T10:29:16.625Z"
}]
When the remote procedure call could not be executed, an error or exception occurred during the execution or the execution of the remote procedure finishes unsuccessfully for any other reason, the server responds by sending a either
[ TYPE_ID_CALLERROR , callID , errorURI , errorDesc ]
or
[ TYPE_ID_CALLERROR , callID , errorURI , errorDesc , errorDetails ]
to the client.
The message is a JSON list consisting of TYPE_ID_CALLERROR, the message type ID as an integer, followed by the callID, the call correlation string that was randomly generated by the client, followed by errorURI, an URI or CURIE identifying the error, followed by errorDesc, a string with an error description.
The errorDesc is always present, MAY be an empty string, and if non-empty SHOULD be a human-readable description of the error. The description is intended to be understood by developers, not end-users.
If errorDetails is present, it MUST be not null, and is used to communicate application error details, defined by the errorURI.
[4, "gwbN3EDtFv6JvNV5",
"http://autobahn.tavendo.de/error#generic",
"math domain error"]
[4, "7bVW5pv8r60ZeL6u",
"http://example.com/error#number_too_big",
"1001 too big for me, max is 1000",
1000]
[4, "AStPd8RS60pfYP8c",
"http://example.com/error#invalid_numbers",
"one or more numbers are multiples of 3",
[0, 3]]
The Publish & Subscribe messaging pattern is realized with 4 messages:
Upon subscribing to a topic via the SUBSCRIBE message, a client will be receiving asynchronous events published to the respective topic via the EVENT message. Clients publish to a topic via the PUBLISH message. An subscription lasts for the duration of a session, unless a client opts out from a previous subscription via the UNSUBSCRIBE message.
A client may subscribe to zero, one or more topics, and clients publish to topics without knowledge of subscribers.
WAMPv1 has no feedback mechanism for when a subscribe or publish fails, i.e. when the subscription or publication is denied. When a client subscribes or publishes, there is no error feedback and a failed action is just silently ignored by the server.
A client requests access to a valid topicURI (or CURIE from Prefix) to receive events published to the given topicURI.
[ TYPE_ID_SUBSCRIBE , topicURI ]
Upon a successful subscription the session will start receiving messages in the EVENT in the context of the topicURI. The request is asynchronous, the server will not return an acknowledgement of the subscription.
Examples
[5, "http://example.com/simple"]
[5, "event:myevent1"]
Calling unsubscribe on a topicURI informs the server to stop delivering messages to the client previously subscribed to that topicURI.
[ TYPE_ID_UNSUBSCRIBE , topicURI ]
Examples
[6, "http://example.com/simple"]
[6, "event:myevent1"]
The client will send an event to all clients connected to the server who have subscribed to the topicURI.
[ TYPE_ID_PUBLISH , topicURI , event ]
[ TYPE_ID_PUBLISH , topicURI , event , excludeMe ]
[ TYPE_ID_PUBLISH , topicURI , event , exclude , eligible ]
If the client publishing their message to topicURI has also Subscribed to that topicURI they can opt to not receive their published event by passing the optional parameter excludeMe to TRUE.
Examples
[7, "http://example.com/simple", "Hello, world!"]
[7, "http://example.com/simple", null]
[7, "http://example.com/event#myevent2",
{
"rand": 0.09187032734575862,
"flag": false,
"num": 23,
"name":
"Kross",
"created": "2012-03-29T10:41:09.864Z"
}]
[7, "event:myevent1",
"hello",
["NwtXQ8rdfPsy-ewS", "dYqgDl0FthI6_hjb"]]
[7, "event:myevent1",
"hello",
[],
["NwtXQ8rdfPsy-ewS"]]
Subscribers receive PubSub events published by subscribers via the EVENT message. The EVENT message contains the topicURI, the topic under which the event was published, and event, the PubSub event payload.
[ TYPE_ID_EVENT , topicURI , event ]
The topicURI MUST be a fully qualified URI for the topic. The event payload MUST always be present, and can be any simple or complex type or null.
Examples
[8, "http://example.com/simple", "Hello, I am a simple event."]
[8, "http://example.com/simple", null]
[8, "http://example.com/event#myevent2",
{
"rand": 0.09187032734575862,
"flag": false,
"num": 23,
"name": "Kross",
"created": "2012-03-29T10:41:09.864Z"
}]