Web Application Messaging Protocol
WAMP is a WebSocket subprotocol registered at IANA, specified[1] to offer routed RPC and PUB/SUB. Its design goal[2] is to provide an open standard for soft real time message exchange between application components and ease the creation of loosely coupled architectures based on microservices. Because of this, it is a suitable ESB[3], fit for developing responsive Web applications or to coordinate multiple connected objects in the IoT[4].
Characteristics
Structure
WAMP requires[5] a reliable, ordered, full-duplex message channel as a transport layer, and by default uses Websocket. However, implementations can use other transports matching these characteristics and communicate with WAMP over raw sockets[6], Unix sockets, HTTP long poll or ZeroMQ[7].
Message serialization assumes integers, strings and ordered sequences types are available, and hence default to JSON. Implementations often provide MessagePack as a faster alternative to JSON, but at the cost of an additional dependency[8].
To identify remote procedures and PUB/SUB topics without conflicts, WAMP also needs an ID space allowing global assignment and resolution. Because the protocol is Web native - Websocket being the preferred transport - HTTP URIs are used.
Workflow
WAMP is architectured around client-client communications, with a central software, the router, dispatching messages between them. The typical data exchange workflow is[9]:
- Clients connect to the router using a transport, establishing a session.
- The router identifies the clients and gives them permissions for the current session.
- A client registers a procedure or subscribes to a topic, using serialised messages carrying unique IDs.
- A client calls a remote procedure or publishes on a topic with this ID.
- The router dispatches the message from one client to another.
This can have subtle variations depending of the underling transport[10]. However, implementation details are hidden to the end user who only programs with the two high-level primitives that are RPC and PUB/SUB.
Security
As WAMP uses Websocket, connections can be wrapped in SSL for encryption. Even when full confidentiality it not established, several mechanisms are implemented to isolate components and avoid MITM attacks. Default implementations ensure that trying to register an already registered procedure will fail.
Routers can define realms as administrative domains, and clients must specify which realm they want to join upon connection. Once joined, the realm will act as a namespace, preventing clients connected to one to be able to do RPC and PUB/SUB using IDs defined in another. Realms also have permissions attached, and can limit the clients to one subset of the REGISTER/CALL/PUB/SUB actions available.
Some realms can be only joined by authenticated clients, using various authentication methods such as using TLS Certificate, cookies or a simple ticket.
Implementations
Clients
As WAMP main targets are Web applications and the Internet of Things, the first client implementations are in languages well established in these industries:
Library | Language |
---|---|
AutobahnAndroid | Java for Dalvik |
AutobahnCpp | C++ 11 |
AutobahnJS | Javascript (browser and NodeJS) |
AutobahnPython | Python |
Erwa | Erlang |
Jawampa | Java |
MDWamp | Objective C |
Minion | PHP |
Thruway | PHP |
WampSharp | C# |
Wampy.js | Javascript (browser only) |
Wamp.io | Javascript (browser and NodeJS) |
The minimum requirements to build a WAMP client are the ability to use sockets and be able to serialise to JSON. This implies a lot of modern languages already have in their standard library what is needed to build a one. Additional features which would add dependencies, such as SSL encryptions or Message Pack serialization, are indeed optional.
However, the persistent nature of Websocket connections requires the use of non blocking libraries and asynchronous APIs. In languages with one official mechanism such as Javascript, Erlang or Go, it's a simple issue. But in the ones with several competing solutions such as Python or PHP, it forces the client author to stand for a specific part of the ecosystem.
For the same reason, integrating legacy projects can also require work. As an example, most popular Web Python frameworks are using WSGI, a synchronous API, and running a WAMP clients inside a WSGI worker needs manual adapters such as crochet.
Router
Routers can be embedded directly into the application code, and for this reason some client libraries also provide a router. But since it's a moving part, it is best used as a swappable black box just like one would consider Apache or Nginx for HTTP:
Router name | Language |
---|---|
Crossbar.io | Python |
Erwa | Erlang |
Jawampa | Java |
Thruway | PHP |
wamp.rt | Javascript (NodeJS only) |
WampSharp | C# |
Wiola | Lua |
Nightlife-Rabbit | Javascript (NodeJS only) |
Tavendo, the company from which originated the protocol, is also the author of Crossbar.io, the de facto router implementation[11]. As they are promoting microservice based architectures, Crossbar.io embeds a service manager, a static file Web server, and a WSGI container. Being written with the Twisted library, it can be setup in production without a proxy, aiming to replace stacks such as Nginx associated with Supervisor and Gunicorn.
However, because Crossbar.io is has Twisted as a dependancy, it can only run on Python 2.7, which means one must install and manage two Python versions in parallel to use the router and a Python 3 client on the same system.
Evolution
WAMP is currently in a transitional state, with the version 1[12] of the specification being deprecated in favour of the version 2[13]. Because the two versions are incompatible, clients and routers implementing only one or the other cannot be used with each others, leading to fragmentation[14].
Since, Crossbar.io, the reference implementation, supports only the version 2, old clients can seldom be used unless ported. Given that allowing an heterogeneous stack of components to communicate with each other is one of the WAMP selling points, having part of the supported languages only enabled to use WAMP 1 can be perceived as a barrier to adoption.
This doesn't prevent the specification to keep being updated. Currently, it is divided into two profiles : basic and advanced. The former is considered stable and libraries implementing WAMP 2 are based on it, while the latter is still a work in progress, and not fully implemented in Crossbar.io.
Use cases
Being a Websocket sub-protocol, WAMP fits naturally anywhere one would use raw web sockets, as a way to synchronize clients such as Web browsers, push notifications to them and allow soft real time collaboration between users[15]. It has also the same limitations, requiring client support, which is missing for Internet Explorer versions older than 10[16]. This is mitigated by the existence of polyfills[17] using more portable technologies such as Flash. In that sense, it's a competitor to Meteor's DDP.
WAMP also targets the IoT, where it is used in the same way as MQTT[18] as a light and efficient medium to orchestrate clusters of connected objects. The implementations in various languages make it suitable to control and monitor small devices such as the Raspberry Pi (in Python) or the Tessel[19] (in Javascript).
At last, WAMP can act as an enterprise service bus, serving as the link between micro-services like one would do with Corba, ZeroMQ, Apache Thrift, SOAP or AMQP.
References
- ^ WAMP basic profile specifications
- ^ "Using WAMP you can build distributed systems out of application components which are loosely coupled and communicate in (soft) real-time".
- ^ A few words about WAMP
- ^ "In this chapter [...] you will learn about the Web Application Messaging Protocol [...] which provide tools and services for developping IoT solutions".
- ^ Crossbar.io router transport
- ^ "WAMP can run over Raw transports instead of WebSocket. Each message is prefixed with a uint32 (big endian) that provides the (serialized) length of the following WAMP message".
- ^ "We could use raw sockets, like the ones Ratchet is built on, but ZeroMQ is a library that just makes sockets easier".
- ^ "Wampy default serializer is JSON, but it also supports msgpack as serializer, but you need to include msgpack.js as dependency".
- ^ WAMP internals bird view diagram
- ^ "The Long-Poll Transport is able to transmit a WAMP session over plain old HTTP 1.0/1.1. This is realized by the Client issuing HTTP/POSTs requests, one for sending, and one for receiving".
- ^ "Crossbar.io is the name of the most full featured router".
- ^ WAMP 1 specification overview
- ^ WAMP 2 specification menu
- ^ "We are waiting the second version for Android Client for a long time".
- ^ WAMP and AngularJS
- ^ "Can is use websockets ?".
- ^ Web socket polyfills
- ^ "Moreover, we compared WAMP with other registered WebSocket subprotocols (MBWS, SOAP and STOMP) in terms of the related features; and with other potential protocols (CoAP and MQTT), in terms of the related practical deployments" (PDF).
- ^ Tessel alarm app with Crossbar.io