idnits 2.17.1 draft-oberstet-hybi-tavendo-wamp-02.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- == There are 58 instances of lines with non-RFC2606-compliant FQDNs in the document. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (October 11, 2015) is 3118 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 6231 -- Looks like a reference, but probably isn't: '0' on line 1218 -- Looks like a reference, but probably isn't: '255' on line 1218 -- Looks like a reference, but probably isn't: '256' on line 1220 -- Looks like a reference, but probably isn't: '1023' on line 1220 -- Looks like a reference, but probably isn't: '33' on line 1661 -- Looks like a reference, but probably isn't: '713845233' on line 1661 -- Looks like a reference, but probably isn't: '5512315355' on line 1715 -- Looks like a reference, but probably isn't: '34' on line 1715 -- Looks like a reference, but probably isn't: '85346237' on line 1730 -- Looks like a reference, but probably isn't: '35' on line 1730 -- Looks like a reference, but probably isn't: '17' on line 1849 -- Looks like a reference, but probably isn't: '239714735' on line 1849 -- Looks like a reference, but probably isn't: '4429313566' on line 1849 -- Looks like a reference, but probably isn't: '65' on line 2016 -- Looks like a reference, but probably isn't: '25349185' on line 2016 -- Looks like a reference, but probably isn't: '2103333224' on line 2054 -- Looks like a reference, but probably isn't: '66' on line 2054 -- Looks like a reference, but probably isn't: '788923562' on line 2069 -- Looks like a reference, but probably isn't: '67' on line 2069 -- Looks like a reference, but probably isn't: '2010' on line 2906 -- Looks like a reference, but probably isn't: '2011' on line 2906 -- Looks like a reference, but probably isn't: '2012' on line 2906 -- Looks like a reference, but probably isn't: '1830' on line 3005 -- Looks like a reference, but probably isn't: '2' on line 6233 -- Looks like a reference, but probably isn't: '3' on line 6235 -- Looks like a reference, but probably isn't: '4' on line 6237 -- Looks like a reference, but probably isn't: '5' on line 6239 -- Looks like a reference, but probably isn't: '6' on line 6241 -- Looks like a reference, but probably isn't: '7' on line 6243 -- Looks like a reference, but probably isn't: '8' on line 6245 -- Looks like a reference, but probably isn't: '9' on line 6247 Summary: 0 errors (**), 0 flaws (~~), 2 warnings (==), 33 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 BiDirectional or Server-Initiated HTTP T. Oberstein 3 Internet-Draft A. Goedde 4 Intended status: Standards Track Tavendo GmbH 5 Expires: April 13, 2016 October 11, 2015 7 The Web Application Messaging Protocol 8 draft-oberstet-hybi-tavendo-wamp-02 10 Abstract 12 This document defines the Web Application Messaging Protocol (WAMP). 13 WAMP is a routed protocol that provides two messaging patterns: 14 Publish & Subscribe and routed Remote Procedure Calls. It is 15 intended to connect application components in distributed 16 applications. WAMP uses WebSocket as its default transport, but can 17 be transmitted via any other protocol that allows for ordered, 18 reliable, bi-directional, and message-oriented communications. 20 Status of This Memo 22 This Internet-Draft is submitted in full conformance with the 23 provisions of BCP 78 and BCP 79. 25 Internet-Drafts are working documents of the Internet Engineering 26 Task Force (IETF). Note that other groups may also distribute 27 working documents as Internet-Drafts. The list of current Internet- 28 Drafts is at http://datatracker.ietf.org/drafts/current/. 30 Internet-Drafts are draft documents valid for a maximum of six months 31 and may be updated, replaced, or obsoleted by other documents at any 32 time. It is inappropriate to use Internet-Drafts as reference 33 material or to cite them other than as "work in progress." 35 This Internet-Draft will expire on April 13, 2016. 37 Copyright Notice 39 Copyright (c) 2015 IETF Trust and the persons identified as the 40 document authors. All rights reserved. 42 This document is subject to BCP 78 and the IETF Trust's Legal 43 Provisions Relating to IETF Documents 44 (http://trustee.ietf.org/license-info) in effect on the date of 45 publication of this document. Please review these documents 46 carefully, as they describe your rights and restrictions with respect 47 to this document. Code Components extracted from this document must 48 include Simplified BSD License text as described in Section 4.e of 49 the Trust Legal Provisions and are provided without warranty as 50 described in the Simplified BSD License. 52 Table of Contents 54 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5 55 1.1. Background . . . . . . . . . . . . . . . . . . . . . . . 5 56 1.2. Protocol Overview . . . . . . . . . . . . . . . . . . . . 6 57 1.3. Design Philosophy . . . . . . . . . . . . . . . . . . . . 7 58 1.3.1. Basic and Advanced Profiles . . . . . . . . . . . . . 7 59 1.3.2. Application Code . . . . . . . . . . . . . . . . . . 8 60 1.3.3. Language Agnostic . . . . . . . . . . . . . . . . . . 8 61 1.3.4. Router Implementation Specifics . . . . . . . . . . . 8 62 1.4. Relationship to WebSocket . . . . . . . . . . . . . . . . 9 63 2. Conformance Requirements . . . . . . . . . . . . . . . . . . 9 64 2.1. Terminology and Other Conventions . . . . . . . . . . . . 9 65 3. Realms, Sessions and Transports . . . . . . . . . . . . . . . 9 66 4. Peers and Roles . . . . . . . . . . . . . . . . . . . . . . . 10 67 4.1. Symmetric Messaging . . . . . . . . . . . . . . . . . . . 10 68 4.2. Remote Procedure Call Roles . . . . . . . . . . . . . . . 10 69 4.3. Publish & Subscribe Roles . . . . . . . . . . . . . . . . 11 70 4.4. Peers with multiple Roles . . . . . . . . . . . . . . . . 11 71 5. Building Blocks . . . . . . . . . . . . . . . . . . . . . . . 12 72 5.1. Identifiers . . . . . . . . . . . . . . . . . . . . . . . 12 73 5.1.1. URIs . . . . . . . . . . . . . . . . . . . . . . . . 12 74 5.1.2. IDs . . . . . . . . . . . . . . . . . . . . . . . . . 14 75 5.2. Serializations . . . . . . . . . . . . . . . . . . . . . 16 76 5.2.1. JSON . . . . . . . . . . . . . . . . . . . . . . . . 17 77 5.2.2. MsgPack . . . . . . . . . . . . . . . . . . . . . . . 17 78 5.3. Transports . . . . . . . . . . . . . . . . . . . . . . . 17 79 5.3.1. WebSocket Transport . . . . . . . . . . . . . . . . . 18 80 5.3.2. Transport and Session Lifetime . . . . . . . . . . . 19 81 6. Messages . . . . . . . . . . . . . . . . . . . . . . . . . . 20 82 6.1. Extensibility . . . . . . . . . . . . . . . . . . . . . . 21 83 6.2. No Polymorphism . . . . . . . . . . . . . . . . . . . . . 21 84 6.3. Structure . . . . . . . . . . . . . . . . . . . . . . . . 22 85 6.4. Message Definitions . . . . . . . . . . . . . . . . . . . 22 86 6.4.1. Session Lifecycle . . . . . . . . . . . . . . . . . . 22 87 6.4.2. Publish & Subscribe . . . . . . . . . . . . . . . . . 23 88 6.4.3. Routed Remote Procedure Calls . . . . . . . . . . . . 24 89 6.5. Message Codes and Direction . . . . . . . . . . . . . . . 26 90 6.6. Extension Messages . . . . . . . . . . . . . . . . . . . 27 91 6.7. Empty Arguments and Keyword Arguments . . . . . . . . . . 27 92 7. Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . 28 93 7.1. Session Establishment . . . . . . . . . . . . . . . . . . 28 94 7.1.1. HELLO . . . . . . . . . . . . . . . . . . . . . . . . 28 95 7.1.2. WELCOME . . . . . . . . . . . . . . . . . . . . . . . 30 96 7.1.3. ABORT . . . . . . . . . . . . . . . . . . . . . . . . 31 98 7.2. Session Closing . . . . . . . . . . . . . . . . . . . . . 32 99 7.2.1. Difference between ABORT and GOODBYE . . . . . . . . 33 100 7.3. Agent Identification . . . . . . . . . . . . . . . . . . 34 101 8. Publish and Subscribe . . . . . . . . . . . . . . . . . . . . 34 102 8.1. Subscribing and Unsubscribing . . . . . . . . . . . . . . 34 103 8.1.1. SUBSCRIBE . . . . . . . . . . . . . . . . . . . . . . 36 104 8.1.2. SUBSCRIBED . . . . . . . . . . . . . . . . . . . . . 36 105 8.1.3. Subscribe ERROR . . . . . . . . . . . . . . . . . . . 37 106 8.1.4. UNSUBSCRIBE . . . . . . . . . . . . . . . . . . . . . 37 107 8.1.5. UNSUBSCRIBED . . . . . . . . . . . . . . . . . . . . 38 108 8.1.6. Unsubscribe ERROR . . . . . . . . . . . . . . . . . . 38 109 8.2. Publishing and Events . . . . . . . . . . . . . . . . . . 39 110 8.2.1. PUBLISH . . . . . . . . . . . . . . . . . . . . . . . 39 111 8.2.2. PUBLISHED . . . . . . . . . . . . . . . . . . . . . . 40 112 8.2.3. Publish ERROR . . . . . . . . . . . . . . . . . . . . 41 113 8.2.4. EVENT . . . . . . . . . . . . . . . . . . . . . . . . 41 114 9. Remote Procedure Calls . . . . . . . . . . . . . . . . . . . 42 115 9.1. Registering and Unregistering . . . . . . . . . . . . . . 43 116 9.1.1. REGISTER . . . . . . . . . . . . . . . . . . . . . . 43 117 9.1.2. REGISTERED . . . . . . . . . . . . . . . . . . . . . 44 118 9.1.3. Register ERROR . . . . . . . . . . . . . . . . . . . 44 119 9.1.4. UNREGISTER . . . . . . . . . . . . . . . . . . . . . 45 120 9.1.5. UNREGISTERED . . . . . . . . . . . . . . . . . . . . 45 121 9.1.6. Unregister ERROR . . . . . . . . . . . . . . . . . . 45 122 9.2. Calling and Invocations . . . . . . . . . . . . . . . . . 46 123 9.2.1. CALL . . . . . . . . . . . . . . . . . . . . . . . . 47 124 9.2.2. INVOCATION . . . . . . . . . . . . . . . . . . . . . 48 125 9.2.3. YIELD . . . . . . . . . . . . . . . . . . . . . . . . 49 126 9.2.4. RESULT . . . . . . . . . . . . . . . . . . . . . . . 50 127 9.2.5. Invocation ERROR . . . . . . . . . . . . . . . . . . 51 128 9.2.6. Call ERROR . . . . . . . . . . . . . . . . . . . . . 52 129 10. Predefined URIs . . . . . . . . . . . . . . . . . . . . . . . 53 130 10.1. Basic Profile . . . . . . . . . . . . . . . . . . . . . 53 131 10.1.1. Incorrect URIs . . . . . . . . . . . . . . . . . . . 53 132 10.1.2. Interaction . . . . . . . . . . . . . . . . . . . . 53 133 10.1.3. Session Close . . . . . . . . . . . . . . . . . . . 54 134 10.1.4. Authorization . . . . . . . . . . . . . . . . . . . 54 135 10.2. Advanced Profile . . . . . . . . . . . . . . . . . . . . 55 136 11. Ordering Guarantees . . . . . . . . . . . . . . . . . . . . . 55 137 11.1. Publish & Subscribe Ordering . . . . . . . . . . . . . . 55 138 11.2. Remote Procedure Call Ordering . . . . . . . . . . . . . 56 139 12. Security Model . . . . . . . . . . . . . . . . . . . . . . . 56 140 12.1. Transport Encryption and Integrity . . . . . . . . . . . 57 141 12.2. Router Authentication . . . . . . . . . . . . . . . . . 57 142 12.3. Client Authentication . . . . . . . . . . . . . . . . . 58 143 12.3.1. Routers are trusted . . . . . . . . . . . . . . . . 58 144 13. Advanced Profile . . . . . . . . . . . . . . . . . . . . . . 58 145 13.1. Messages . . . . . . . . . . . . . . . . . . . . . . . . 59 146 13.1.1. Message Definitions . . . . . . . . . . . . . . . . 59 147 13.1.2. Message Codes and Direction . . . . . . . . . . . . 59 148 13.2. Features . . . . . . . . . . . . . . . . . . . . . . . . 60 149 13.2.1. RPC Features . . . . . . . . . . . . . . . . . . . . 60 150 13.2.2. PubSub Features . . . . . . . . . . . . . . . . . . 61 151 13.2.3. Other Advanced Features . . . . . . . . . . . . . . 61 152 13.3. Advanced RPC Features . . . . . . . . . . . . . . . . . 62 153 13.3.1. Progressive Call Results . . . . . . . . . . . . . . 62 154 13.3.2. Progressive Calls . . . . . . . . . . . . . . . . . 67 155 13.3.3. Call Timeouts . . . . . . . . . . . . . . . . . . . 67 156 13.3.4. Call Canceling . . . . . . . . . . . . . . . . . . . 68 157 13.3.5. Caller Identification . . . . . . . . . . . . . . . 71 158 13.3.6. Call Trust Levels . . . . . . . . . . . . . . . . . 72 159 13.3.7. Registration Meta API . . . . . . . . . . . . . . . 72 160 13.3.8. Pattern-based Registrations . . . . . . . . . . . . 79 161 13.3.9. Shared Registration . . . . . . . . . . . . . . . . 82 162 13.3.10. Sharded Registration . . . . . . . . . . . . . . . . 84 163 13.3.11. Registration Revocation . . . . . . . . . . . . . . 85 164 13.3.12. Procedure Reflection . . . . . . . . . . . . . . . . 85 165 13.4. Advanced PubSub Features . . . . . . . . . . . . . . . . 86 166 13.4.1. Subscriber Black- and Whitelisting . . . . . . . . . 86 167 13.4.2. Publisher Exclusion . . . . . . . . . . . . . . . . 91 168 13.5. Feature Definition . . . . . . . . . . . . . . . . . . . 91 169 13.6. Feature Announcement . . . . . . . . . . . . . . . . . . 91 170 13.6.1. Publisher Identification . . . . . . . . . . . . . . 92 171 13.6.2. Publication Trust Levels . . . . . . . . . . . . . . 93 172 13.6.3. Subscription Meta API . . . . . . . . . . . . . . . 93 173 13.6.4. Pattern-based Subscriptions . . . . . . . . . . . . 99 174 13.6.5. Sharded Subscriptions . . . . . . . . . . . . . . . 102 175 13.6.6. Event History . . . . . . . . . . . . . . . . . . . 102 176 13.6.7. Registration Revocation . . . . . . . . . . . . . . 104 177 13.6.8. Topic Reflection . . . . . . . . . . . . . . . . . . 104 178 13.7. Other Advanced Features . . . . . . . . . . . . . . . . 104 179 13.7.1. Session Meta API . . . . . . . . . . . . . . . . . . 104 180 13.7.2. Authentication . . . . . . . . . . . . . . . . . . . 108 181 13.7.3. Alternative Transports . . . . . . . . . . . . . . . 116 182 14. Binary conversion of JSON Strings . . . . . . . . . . . . . . 131 183 14.1. Python . . . . . . . . . . . . . . . . . . . . . . . . . 132 184 14.2. JavaScript . . . . . . . . . . . . . . . . . . . . . . . 133 185 15. Security Considerations . . . . . . . . . . . . . . . . . . . 134 186 16. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 135 187 17. Contributors . . . . . . . . . . . . . . . . . . . . . . . . 135 188 18. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 135 189 19. References . . . . . . . . . . . . . . . . . . . . . . . . . 135 190 19.1. Normative References . . . . . . . . . . . . . . . . . . 135 191 19.2. Informative References . . . . . . . . . . . . . . . . . 135 192 19.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 135 193 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 136 195 1. Introduction 197 1.1. Background 199 _This section is non-normative._ 201 The WebSocket protocol brings bi-directional real-time connections to 202 the browser. It defines an API at the message level, requiring users 203 who want to use WebSocket connections in their applications to define 204 their own semantics on top of it. 206 The Web Application Messaging Protocol (WAMP) is intended to provide 207 application developers with the semantics they need to handle 208 messaging between components in distributed applications. 210 WAMP was initially defined as a WebSocket sub-protocol, which 211 provided Publish & Subscribe (PubSub) functionality as well as Remote 212 Procedure Calls (RPC) for procedures implemented in a WAMP router. 213 Feedback from implementers and users of this was included in a second 214 version of the protocol which this document defines. Among the 215 changes was that WAMP can now run over any transport which is 216 message-oriented, ordered, reliable, and bi-directional. 218 WAMP is a routed protocol, with all components connecting to a _WAMP 219 Router_, where the WAMP Router performs message routing between the 220 components. 222 WAMP provides two messaging patterns: _Publish & Subscribe_ and 223 _routed Remote Procedure Calls_. 225 Publish & Subscribe (PubSub) is an established messaging pattern 226 where a component, the _Subscriber_, informs the router that it wants 227 to receive information on a topic (i.e., it subscribes to a topic). 228 Another component, a _Publisher_, can then publish to this topic, and 229 the router distributes events to all Subscribers. 231 Routed Remote Procedure Calls (RPCs) rely on the same sort of 232 decoupling that is used by the Publish & Subscribe pattern. A 233 component, the _Callee_, announces to the router that it provides a 234 certain procedure, identified by a procedure name. Other components, 235 _Callers_, can then call the procedure, with the router invoking the 236 procedure on the Callee, receiving the procedure's result, and then 237 forwarding this result back to the Caller. Routed RPCs differ from 238 traditional client-server RPCs in that the router serves as an 239 intermediary between the Caller and the Callee. 241 The decoupling in routed RPCs arises from the fact that the Caller is 242 no longer required to have knowledge of the Callee; it merely needs 243 to know the identifier of the procedure it wants to call. There is 244 also no longer a need for a direct connection between the caller and 245 the callee, since all traffic is routed. This enables the calling of 246 procedures in components which are not reachable externally (e.g. on 247 a NATted connection) but which can establish an outgoing connection 248 to the WAMP router. 250 Combining these two patterns into a single protocol allows it to be 251 used for the entire messaging requirements of an application, thus 252 reducing technology stack complexity, as well as networking 253 overheads. 255 1.2. Protocol Overview 257 _This section is non-normative._ 259 The PubSub messaging pattern defines three roles: _Subscribers_ and 260 _Publishers_, which communicate via a _Broker_. 262 The routed RPC messaging pattern also defines three roles: _Callers_ 263 and _Callees_, which communicate via a _Dealer_. 265 WAMP Connections are established by _Clients_ to a _Router_. 266 Connections can use any transport that is message-based, ordered, 267 reliable and bi-directional, with WebSocket as the default transport. 269 A Router is a component which implements one or both of the Broker 270 and Dealer roles. A Client is a component which implements any or 271 all of the Subscriber, Publisher, Caller, or Callee roles. 273 WAMP _Connections_ are established by Clients to a Router. 274 Connections can use any transport which is message-oriented, ordered, 275 reliable and bi-directional, with WebSocket as the default transport. 277 WAMP _Sessions_ are established over a WAMP Connection. A WAMP 278 Session is joined to a _Realm_ on a Router. Routing occurs only 279 between WAMP Sessions that have joined the same Realm. 281 The _WAMP Basic Profile_ defines the parts of the protocol that are 282 required to establish a WAMP connection, as well as for basic 283 interactions between the four client and two router roles. WAMP 284 implementations are required to implement the Basic Profile, at 285 minimum. 287 The _WAMP Advanced Profile_ defines additions to the Basic Profile 288 which greatly extend the utility of WAMP in real-world applications. 289 WAMP implementations may support any subset of the Advanced Profile 290 features. They are required to announce those supported features 291 during session establishment. 293 1.3. Design Philosophy 295 _This section is non-normative._ 297 WAMP was designed to be performant, safe and easy to implement. Its 298 entire design was driven by a implement, get feedback, adjust cycle. 300 An initial version of the protocol was publicly released in March 301 2012. The intent was to gain insight through implementation and use, 302 and integrate these into a second version of the protocol, where 303 there would be no regard for compatibility between the two versions. 304 Several interoperable, independent implementations were released, and 305 feedback from the implementers and users was collected. 307 The second version of the protocol, which this RFC covers, integrates 308 this feedback. Routed Remote Procedure Calls are one outcome of 309 this, where the initial version of the protocol only allowed the 310 calling of procedures provided by the router. Another, related 311 outcome was the strict separation of routing and application logic. 313 While WAMP was originally developed to use WebSocket as a transport, 314 with JSON for serialization, experience in the field revealed that 315 other transports and serialization formats were better suited to some 316 use cases. For instance, with the use of WAMP in the Internet of 317 Things sphere, resource constraints play a much larger role than in 318 the browser, so any reduction of resource usage in WAMP 319 implementations counts. This lead to the decoupling of WAMP from any 320 particular transport or serialization, with the establishment of 321 minimum requirements for both. 323 1.3.1. Basic and Advanced Profiles 325 This document first describes a Basic Profile for WAMP in its 326 entirety, before describing an Advanced Profile which extends the 327 basic functionality of WAMP. 329 The separation into Basic and Advanced Profiles is intended to extend 330 the reach of the protocol. It allows implementations to start out 331 with a minimal, yet operable and useful set of features, and to 332 expand that set from there. It also allows implementations that are 333 tailored for resource-constrained environments, where larger feature 334 sets would not be possible. Here implementers can weigh between 335 resource constraints and functionality requirements, then implement 336 an optimal feature set for the circumstances. 338 Advanced Profile features are announced during session establishment, 339 so that different implementations can adjust their interactions to 340 fit the commonly supported feature set. 342 1.3.2. Application Code 344 WAMP is designed for application code to run within Clients, i.e. 345 _Peers_ having the roles Callee, Caller, Publisher, and Subscriber. 347 Routers, i.e. Peers of the roles Brokers and Dealers are responsible 348 for *generic call and event routing* and do not run application code. 350 This allows the transparent exchange of Broker and Dealer 351 implementations without affecting the application and to distribute 352 and deploy application components flexibly. 354 Note that a *program* that implements, for instance, the Dealer 355 role might at the same time implement, say, a built-in Callee. It 356 is the Dealer and Broker that are generic, not the program. 358 1.3.3. Language Agnostic 360 WAMP is language agnostic, i.e. can be implemented in any programming 361 language. At the level of arguments that may be part of a WAMP 362 message, WAMP takes a 'superset of all' approach. WAMP 363 implementations may support features of the implementing language for 364 use in arguments, e.g. keyword arguments. 366 1.3.4. Router Implementation Specifics 368 This specification only deals with the protcol level. Specific WAMP 369 Broker and Dealer implementations may differ in aspects such as 370 support for: 372 o router networks (clustering and federation), 374 o authentication and authorization schemes, 376 o message persistence, and, 378 o management and monitoring. 380 The definition and documentation of such Router features is outside 381 the scope of this document. 383 1.4. Relationship to WebSocket 385 WAMP uses WebSocket as its default transport binding, and is a 386 registered WebSocket subprotocol. 388 2. Conformance Requirements 390 All diagrams, examples, and notes in this specification are non- 391 normative, as are all sections explicitly marked non-normative. 392 Everything else in this specification is normative. 394 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 395 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 396 document are to be interpreted as described in RFC 2119 [RFC2119]. 398 Requirements phrased in the imperative as part of algorithms (such as 399 "strip any leading space characters" or "return false and abort these 400 steps") are to be interpreted with the meaning of the key word 401 ("MUST", "SHOULD", "MAY", etc.) used in introducing the algorithm. 403 Conformance requirements phrased as algorithms or specific steps MAY 404 be implemented in any manner, so long as the end result is 405 equivalent. 407 2.1. Terminology and Other Conventions 409 Key terms such as named algorithms or definitions are indicated like 410 _this_ when they first occur, and are capitalized throughout the 411 text. 413 3. Realms, Sessions and Transports 415 A Realm is a WAMP routing and administrative domain, optionally 416 protected by authentication and authorization. WAMP messages are 417 only routed within a Realm. 419 A Session is a transient conversation between two Peers attached to a 420 Realm and running over a Transport. 422 A Transport connects two WAMP Peers and provides a channel over which 423 WAMP messages for a WAMP Session can flow in both directions. 425 WAMP can run over any Transport which is message-based, 426 bidirectional, reliable and ordered. 428 The default transport for WAMP is WebSocket [RFC6455], where WAMP is 429 an officially registered [1] subprotocol. 431 4. Peers and Roles 433 A WAMP Session connects two Peers, a Client and a Router. Each WAMP 434 Peer MUST implement one role, and MAY implement more roles. 436 A Client MAY implement any combination of the Roles: 438 o Callee 440 o Caller 442 o Publisher 444 o Subscriber 446 and a Router MAY implement either or both of the Roles: 448 o Dealer 450 o Broker 452 This document describes WAMP as in client-to-router communication. 453 Direct client-to-client communication is not supported by WAMP. 454 Router-to-router communication MAY be defined by a specific router 455 implementation. 457 4.1. Symmetric Messaging 459 It is important to note that though the establishment of a Transport 460 might have a inherent asymmetry (like a TCP client establishing a 461 WebSocket connection to a server), and Clients establish WAMP 462 sessions by attaching to Realms on Routers, WAMP itself is designed 463 to be fully symmetric for application components. 465 After the transport and a session have been established, any 466 application component may act as Caller, Callee, Publisher and 467 Subscriber at the same time. And Routers provide the fabric on top 468 of which WAMP runs a symmetric application messaging service. 470 4.2. Remote Procedure Call Roles 472 The Remote Procedure Call messaging pattern involves peers of three 473 different roles: 475 o Callee (Client) 477 o Caller (Client) 478 o Dealer (Router) 480 A Caller issues calls to remote procedures by providing the procedure 481 URI and any arguments for the call. The Callee will execute the 482 procedure using the supplied arguments to the call and return the 483 result of the call to the Caller. 485 Callees register procedures they provide with Dealers. Callers 486 initiate procedure calls first to Dealers. Dealers route calls 487 incoming from Callers to Callees implementing the procedure called, 488 and route call results back from Callees to Callers. 490 The Caller and Callee will usually run application code, while the 491 Dealer works as a generic router for remote procedure calls 492 decoupling Callers and Callees. 494 4.3. Publish & Subscribe Roles 496 The Publish & Subscribe messaging pattern involves peers of three 497 different roles: 499 o Subscriber (Client) 501 o Publisher (Client) 503 o Broker (Router) 505 A Publishers publishes events to topics by providing the topic URI 506 and any payload for the event. Subscribers of the topic will receive 507 the event together with the event payload. 509 Subscribers subscribe to topics they are interested in with Brokers. 510 Publishers initiate publication first at Brokers. Brokers route 511 events incoming from Publishers to Subscribers that are subscribed to 512 respective topics. 514 The Publisher and Subscriber will usually run application code, while 515 the Broker works as a generic router for events decoupling Publishers 516 from Subscribers. 518 4.4. Peers with multiple Roles 520 Note that Peers might implement more than one role: e.g. a Peer might 521 act as Caller, Publisher and Subscriber at the same time. Another 522 Peer might act as both a Broker and a Dealer. 524 5. Building Blocks 526 WAMP is defined with respect to the following building blocks 528 1. Identifiers 530 2. Serializations 532 3. Transports 534 For each building block, WAMP only assumes a defined set of 535 requirements, which allows to run WAMP variants with different 536 concrete bindings. 538 5.1. Identifiers 540 5.1.1. URIs 542 WAMP needs to identify the following *persistent* resources: 544 1. Topics 546 2. Procedures 548 3. Errors 550 These are identified in WAMP using _Uniform Resource Identifiers_ 551 (URIs) [RFC3986] that MUST be Unicode strings. 553 When using JSON as WAMP serialization format, URIs (as other 554 strings) are transmitted in UTF-8 [RFC3629] encoding. 556 _Examples_ 558 o "com.myapp.mytopic1" 560 o "com.myapp.myprocedure1" 562 o "com.myapp.myerror1" 564 The URIs are understood to form a single, global, hierarchical 565 namespace for WAMP. 567 The namespace is unified for topics, procedures and errors - these 568 different resource types do NOT have separate namespaces. 570 To avoid resource naming conflicts, the package naming convention 571 from Java is used, where URIs SHOULD begin with (reversed) domain 572 names owned by the organization defining the URI. 574 5.1.1.1. Relaxed/Loose URIs 576 URI components (the parts between two "."s, the head part up to the 577 first ".", the tail part after the last ".") MUST NOT contain a ".", 578 "#" or whitespace characters and MUST NOT be empty (zero-length 579 strings). 581 The restriction not to allow "." in component strings is due to 582 the fact that "." is used to separate components, and WAMP 583 associates semantics with resource hierarchies, such as in 584 pattern-based subscriptions that are part of the Advanced Profile. 585 The restriction not to allow empty (zero-length) strings as 586 components is due to the fact that this may be used to denote 587 wildcard components with pattern-based subscriptions and 588 registrations in the Advanced Profile. The character "#" is not 589 allowed since this is reserved for internal use by Dealers and 590 Brokers. 592 As an example, the following regular expression could be used in 593 Python to check URIs according to above rules: 595 596 ## loose URI check disallowing empty URI components 597 pattern = re.compile(r"^([^\s\.#]+\.)*([^\s\.#]+)$") 598 600 When empty URI components are allowed (which is the case for specific 601 messages that are part of the Advanced Profile), this following 602 regular expression can be used (shown used in Python): 604 605 ## loose URI check allowing empty URI components 606 pattern = re.compile(r"^(([^\s\.#]+\.)|\.)*([^\s\.#]+)?$") 607 609 5.1.1.2. Strict URIs 611 While the above rules MUST be followed, following a stricter URI rule 612 is recommended: URI components SHOULD only contain letters, digits 613 and "_". 615 As an example, the following regular expression could be used in 616 Python to check URIs according to the above rules: 618 619 ## strict URI check disallowing empty URI components 620 pattern = re.compile(r"^([0-9a-z_]+\.)*([0-9a-z_]+)$") 621 623 When empty URI components are allowed (which is the case for specific 624 messages that are part of the Advanced Profile), the following 625 regular expression can be used (shown in Python): 627 628 ## strict URI check allowing empty URI components 629 pattern = re.compile(r"^(([0-9a-z_]+\.)|\.)*([0-9a-z_]+)?$") 630 632 Following the suggested regular expression will make URI 633 components valid identifiers in most languages (modulo URIs 634 starting with a digit and language keywords) and the use of lower- 635 case only will make those identifiers unique in languages that 636 have case-insensitive identifiers. Following this suggestion can 637 allow implementations to map topics, procedures and errors to the 638 language environment in a completely transparent way. 640 5.1.1.3. Reserved URIs 642 Further, application URIs MUST NOT use "wamp" as a first URI 643 component, since this is reserved for URIs predefined with the WAMP 644 protocol itself. 646 _Examples_ 648 o "wamp.error.not_authorized" 650 o "wamp.error.procedure_already_exists" 652 5.1.2. IDs 654 WAMP needs to identify the following ephemeral entities each in the 655 scope noted: 657 1. Sessions (_global scope_) 659 2. Publications (_global scope_) 661 3. Subscriptions (_router scope_) 663 4. Registrations (_router scope_) 665 5. Requests (_session scope_) 666 These are identified in WAMP using IDs that are integers between 667 (inclusive) *0* and *2^53* (9007199254740992): 669 o IDs in the _global scope_ MUST be drawn _randomly_ from a _uniform 670 distribution_ over the complete range [0, 2^53] 672 o IDs in the _router scope_ can be chosen freely by the specific 673 router implementation 675 o IDs in the _session scope_ SHOULD be incremented by 1 beginning 676 with 1 (for each direction - _Client-to-Router_ and _Router-to- 677 Client_) 679 The reason to choose the specific upper bound is that 2^53 is the 680 largest integer such that this integer and _all_ (positive) 681 smaller integers can be represented exactly in IEEE-754 doubles. 682 Some languages (e.g. JavaScript) use doubles as their sole number 683 type. Most languages do have signed and unsigned 64-bit integer 684 types that both can hold any value from the specified range. 686 The following is a complete list of usage of IDs in the three 687 categories for all WAMP messages. For a full definition of these see 688 Section 6. 690 5.1.2.1. Global Scope IDs 692 o "WELCOME.Session" 694 o "PUBLISHED.Publication" 696 o "EVENT.Publication" 698 5.1.2.2. Router Scope IDs 700 o "EVENT.Subscription" 702 o "SUBSCRIBED.Subscription" 704 o "REGISTERED.Registration" 706 o "UNSUBSCRIBE.Subscription" 708 o "UNREGISTER.Registration" 710 o "INVOCATION.Registration" 712 5.1.2.3. Session Scope IDs 714 o "ERROR.Request" 716 o "PUBLISH.Request" 718 o "PUBLISHED.Request" 720 o "SUBSCRIBE.Request" 722 o "SUBSCRIBED.Request" 724 o "UNSUBSCRIBE.Request" 726 o "UNSUBSCRIBED.Request" 728 o "CALL.Request" 730 o "CANCEL.Request" 732 o "RESULT.Request" 734 o "REGISTER.Request" 736 o "REGISTERED.Request" 738 o "UNREGISTER.Request" 740 o "UNREGISTERED.Request" 742 o "INVOCATION.Request" 744 o "INTERRUPT.Request" 746 o "YIELD.Request" 748 5.2. Serializations 750 WAMP is a message based protocol that requires serialization of 751 messages to octet sequences to be sent out on the wire. 753 A message _serialization_ format is assumed that (at least) provides 754 the following types: 756 o "integer" (non-negative) 758 o "string" (UTF-8 encoded Unicode) 759 o "bool" 761 o "list" 763 o "dict" (with string keys) 765 WAMP _itself_ only uses the above types, e.g. it does not use the 766 JSON data types "number" (non-integer) and "null". The 767 _application payloads_ transmitted by WAMP (e.g. in call arguments 768 or event payloads) may use other types a concrete serialization 769 format supports. 771 There is no required serialization or set of serializations for WAMP 772 implementations (but each implementation MUST, of course, implement 773 at least one serialization format). Routers SHOULD implement more 774 than one serialization format, enabling components using different 775 kinds of serializations to connect to each other. 777 WAMP defines two bindings for message _serialization_: 779 1. JSON 781 2. MsgPack 783 Other bindings for _serialization_ may be defined in future WAMP 784 versions. 786 5.2.1. JSON 788 With JSON serialization, each WAMP message is serialized according to 789 the JSON specification as described in RFC4627. 791 Further, binary data follows a convention for conversion to JSON 792 strings. For details see the Appendix. 794 5.2.2. MsgPack 796 With MsgPack serialization, each WAMP message is serialized according 797 to the MsgPack specification. 799 Version 5 or later of MsgPack MUST BE used, since this version is 800 able to differentiate between strings and binary values. 802 5.3. Transports 804 WAMP assumes a _transport_ with the following characteristics: 806 1. message-based 807 2. reliable 809 3. ordered 811 4. bidirectional (full-duplex) 813 There is no required transport or set of transports for WAMP 814 implementations (but each implementation MUST, of course, implement 815 at least one transport). Routers SHOULD implement more than one 816 transport, enabling components using different kinds of transports to 817 connect in an application. 819 5.3.1. WebSocket Transport 821 The default transport binding for WAMP is WebSocket. 823 In the Basic Profile, WAMP messages are transmitted as WebSocket 824 messages: each WAMP message is transmitted as a separate WebSocket 825 message (not WebSocket frame). The Advanced Profile may define other 826 modes, e.g. a *batched mode* where multiple WAMP messages are 827 transmitted via single WebSocket message. 829 The WAMP protocol MUST BE negotiated during the WebSocket opening 830 handshake between Peers using the WebSocket subprotocol negotiation 831 mechanism. 833 WAMP uses the following WebSocket subprotocol identifiers for 834 unbatched modes: 836 o "wamp.2.json" 838 o "wamp.2.msgpack" 840 With "wamp.2.json", _all_ WebSocket messages MUST BE of type *text* 841 (UTF8 encoded payload) and use the JSON message serialization. 843 With "wamp.2.msgpack", _all_ WebSocket messages MUST BE of type 844 *binary* and use the MsgPack message serialization. 846 To avoid incompatibilities merely due to naming conflicts with 847 WebSocket subprotocol identifiers, implementers SHOULD register 848 identifiers for additional serialization formats with the official 849 WebSocket subprotocol registry. 851 5.3.2. Transport and Session Lifetime 853 WAMP implementations MAY choose to tie the lifetime of the underlying 854 transport connection for a WAMP connection to that of a WAMP session, 855 i.e. establish a new transport-layer connection as part of each new 856 session establishment. They MAY equally choose to allow re-use of a 857 transport connection, allowing subsequent WAMP sessions to be 858 established using the same transport connection. 860 The diagram below illustrates the full transport connection and 861 session lifecycle for an implementation which uses WebSocket over TCP 862 as the transport and allows the re-use of a transport connection. 864 ,------. ,------. 865 | Peer | | Peer | 866 `--+---' `--+---' 868 TCP established 869 |<----------------------------------------->| 870 | | 871 | TLS established | 872 |+<--------------------------------------->+| 873 |+ +| 874 |+ WebSocket established +| 875 |+|<------------------------------------->|+| 876 |+| |+| 877 |+| WAMP established |+| 878 |+|+<----------------------------------->+|+| 879 |+|+ +|+| 880 |+|+ +|+| 881 |+|+ WAMP closed +|+| 882 |+|+<----------------------------------->+|+| 883 |+| |+| 884 |+| |+| 885 |+| WAMP established |+| 886 |+|+<----------------------------------->+|+| 887 |+|+ +|+| 888 |+|+ +|+| 889 |+|+ WAMP closed +|+| 890 |+|+<----------------------------------->+|+| 891 |+| |+| 892 |+| WebSocket closed |+| 893 |+|<------------------------------------->|+| 894 |+ +| 895 |+ TLS closed +| 896 |+<--------------------------------------->+| 897 | | 898 | TCP closed | 899 |<----------------------------------------->| 901 ,--+---. ,--+---. 902 | Peer | | Peer | 903 `------' `------' 905 6. Messages 907 All WAMP messages are a "list" with a first element "MessageType" 908 followed by one or more message type specific elements: 910 [MessageType|integer, ... one or more message type specific 911 elements ...] 913 The notation "Element|type" denotes a message element named "Element" 914 of type "type", where "type" is one of 916 o "uri": a string URI as defined in Section 5.1.1 918 o "id": an integer ID as defined in Section 5.1.2 920 o "integer": a non-negative integer 922 o "string": a Unicode string, including the empty string 924 o "bool": a boolean value ("true" or "false") - integers MUST NOT be 925 used instead of boolean value 927 o "dict": a dictionary (map) where keys MUST be strings, keys MUST 928 be unique and serialization order is undefined (left to the 929 serializer being used) 931 o "list": a list (array) where items can be again any of this 932 enumeration 934 _Example_ 936 A "SUBSCRIBE" message has the following format 938 [SUBSCRIBE, Request|id, Options|dict, Topic|uri] 940 Here is an example message conforming to the above format 942 [32, 713845233, {}, "com.myapp.mytopic1"] 944 6.1. Extensibility 946 Some WAMP messages contain "Options|dict" or "Details|dict" elements. 947 This allows for future extensibility and implementations that only 948 provide subsets of functionality by ignoring unimplemented 949 attributes. Keys in "Options" and "Details" MUST be of type "string" 950 and MUST match the regular expression "[a-z][a-z0-9_]{2,}" for WAMP 951 _predefined_ keys. Implementations MAY use implementation-specific 952 keys that MUST match the regular expression "_[a-z0-9_]{3,}". 953 Attributes unknown to an implementation MUST be ignored. 955 6.2. No Polymorphism 957 For a given "MessageType" _and_ number of message elements the 958 expected types are uniquely defined. Hence there are no polymorphic 959 messages in WAMP. This leads to a message parsing and validation 960 control flow that is efficient, simple to implement and simple to 961 code for rigorous message format checking. 963 6.3. Structure 965 The _application_ payload (that is call arguments, call results, 966 event payload etc) is always at the end of the message element list. 967 The rationale is: Brokers and Dealers have no need to inspect (parse) 968 the application payload. Their business is call/event routing. 969 Having the application payload at the end of the list allows Brokers 970 and Dealers to skip parsing it altogether. This can improve 971 efficiency and performance. 973 6.4. Message Definitions 975 WAMP defines the following messages that are explained in detail in 976 the following sections. 978 The messages concerning the WAMP session itself are mandatory for all 979 Peers, i.e. a Client MUST implement "HELLO", "ABORT" and "GOODBYE", 980 while a Router MUST implement "WELCOME", "ABORT" and "GOODBYE". 982 All other messages are mandatory _per role_, i.e. in an 983 implementation that only provides a Client with the role of Publisher 984 MUST additionally implement sending "PUBLISH" and receiving 985 "PUBLISHED" and "ERROR" messages. 987 6.4.1. Session Lifecycle 989 6.4.1.1. HELLO 991 Sent by a Client to initiate opening of a WAMP session to a Router 992 attaching to a Realm. 994 [HELLO, Realm|uri, Details|dict] 996 6.4.1.2. WELCOME 998 Sent by a Router to accept a Client. The WAMP session is now open. 1000 [WELCOME, Session|id, Details|dict] 1002 6.4.1.3. ABORT 1004 Sent by a Peer*to abort the opening of a WAMP session. No response 1005 is expected. 1007 [ABORT, Details|dict, Reason|uri] 1009 6.4.1.4. GOODBYE 1011 Sent by a Peer to close a previously opened WAMP session. Must be 1012 echo'ed by the receiving Peer. 1014 [GOODBYE, Details|dict, Reason|uri] 1016 6.4.1.5. ERROR 1018 Error reply sent by a Peer as an error response to different kinds of 1019 requests. 1021 [ERROR, REQUEST.Type|int, REQUEST.Request|id, Details|dict, 1022 Error|uri] 1024 [ERROR, REQUEST.Type|int, REQUEST.Request|id, Details|dict, 1025 Error|uri, Arguments|list] 1027 [ERROR, REQUEST.Type|int, REQUEST.Request|id, Details|dict, 1028 Error|uri, Arguments|list, ArgumentsKw|dict] 1030 6.4.2. Publish & Subscribe 1032 6.4.2.1. PUBLISH 1034 Sent by a Publisher to a Broker to publish an event. 1036 [PUBLISH, Request|id, Options|dict, Topic|uri] 1038 [PUBLISH, Request|id, Options|dict, Topic|uri, 1039 Arguments|list] 1041 [PUBLISH, Request|id, Options|dict, Topic|uri, 1042 Arguments|list, ArgumentsKw|dict] 1044 6.4.2.2. PUBLISHED 1046 Acknowledge sent by a Broker to a Publisher for acknowledged 1047 publications. 1049 [PUBLISHED, PUBLISH.Request|id, Publication|id] 1051 6.4.2.3. SUBSCRIBE 1053 Subscribe request sent by a Subscriber to a Broker to subscribe to a 1054 topic. 1056 [SUBSCRIBE, Request|id, Options|dict, Topic|uri] 1058 6.4.2.4. SUBSCRIBED 1060 Acknowledge sent by a Broker to a Subscriber to acknowledge a 1061 subscription. 1063 [SUBSCRIBED, SUBSCRIBE.Request|id, Subscription|id] 1065 6.4.2.5. UNSUBSCRIBE 1067 Unsubscribe request sent by a Subscriber to a Broker to unsubscribe a 1068 subscription. 1070 [UNSUBSCRIBE, Request|id, SUBSCRIBED.Subscription|id] 1072 6.4.2.6. UNSUBSCRIBED 1074 Acknowledge sent by a Broker to a Subscriber to acknowledge 1075 unsubscription. 1077 [UNSUBSCRIBED, UNSUBSCRIBE.Request|id] 1079 6.4.2.7. EVENT 1081 Event dispatched by Broker to Subscribers for subscriptions the event 1082 was matching. 1084 [EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id, 1085 Details|dict] 1087 [EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id, 1088 Details|dict, PUBLISH.Arguments|list] 1090 [EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id, 1091 Details|dict, PUBLISH.Arguments|list, 1092 PUBLISH.ArgumentsKw|dict] 1094 An event is dispatched to a Subscriber for a given 1095 "Subscription|id" _only once_. On the other hand, a Subscriber 1096 that holds subscriptions with different "Subscription|id"s that 1097 all match a given event will receive the event on each matching 1098 subscription. 1100 6.4.3. Routed Remote Procedure Calls 1101 6.4.3.1. CALL 1103 Call as originally issued by the _Caller_ to the _Dealer_. 1105 [CALL, Request|id, Options|dict, Procedure|uri] 1107 [CALL, Request|id, Options|dict, Procedure|uri, Arguments|list] 1109 [CALL, Request|id, Options|dict, Procedure|uri, Arguments|list, 1110 ArgumentsKw|dict] 1112 6.4.3.2. RESULT 1114 Result of a call as returned by _Dealer_ to _Caller_. 1116 [RESULT, CALL.Request|id, Details|dict] 1118 [RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list] 1120 [RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list, 1121 YIELD.ArgumentsKw|dict] 1123 6.4.3.3. REGISTER 1125 A _Callees_ request to register an endpoint at a _Dealer_. 1127 [REGISTER, Request|id, Options|dict, Procedure|uri] 1129 6.4.3.4. REGISTERED 1131 Acknowledge sent by a _Dealer_ to a _Callee_ for successful 1132 registration. 1134 [REGISTERED, REGISTER.Request|id, Registration|id] 1136 6.4.3.5. UNREGISTER 1138 A _Callees_ request to unregister a previously established 1139 registration. 1141 [UNREGISTER, Request|id, REGISTERED.Registration|id] 1143 6.4.3.6. UNREGISTERED 1145 Acknowledge sent by a _Dealer_ to a _Callee_ for successful 1146 unregistration. 1148 [UNREGISTERED, UNREGISTER.Request|id] 1150 6.4.3.7. INVOCATION 1152 Actual invocation of an endpoint sent by _Dealer_ to a _Callee_. 1154 [INVOCATION, Request|id, REGISTERED.Registration|id, 1155 Details|dict] 1157 [INVOCATION, Request|id, REGISTERED.Registration|id, 1158 Details|dict, C* Arguments|list] 1160 [INVOCATION, Request|id, REGISTERED.Registration|id, 1161 Details|dict, CALL.Arguments|list, CALL.ArgumentsKw|dict] 1163 6.4.3.8. YIELD 1165 Actual yield from an endpoint sent by a _Callee_ to _Dealer_. 1167 [YIELD, INVOCATION.Request|id, Options|dict] 1169 [YIELD, INVOCATION.Request|id, Options|dict, Arguments|list] 1171 [YIELD, INVOCATION.Request|id, Options|dict, Arguments|list, 1172 ArgumentsKw|dict] 1174 6.5. Message Codes and Direction 1176 The following table lists the message type code for *all 25 messages 1177 defined in the WAMP basic profile* and their direction between peer 1178 roles. 1180 Reserved codes may be used to identify additional message types in 1181 future standards documents. 1183 "Tx" indicates the message is sent by the respective role, and 1184 "Rx" indicates the message is received by the respective role. 1186 +-----+----------------+------+------+------+------+-------+--------+ 1187 | Cod | Message | Pub | Brk | Subs | Calr | Dealr | Callee | 1188 +-----+----------------+------+------+------+------+-------+--------+ 1189 | 1 | "HELLO" | Tx | Rx | Tx | Tx | Rx | Tx | 1190 | 2 | "WELCOME" | Rx | Tx | Rx | Rx | Tx | Rx | 1191 | 3 | "ABORT" | Rx | TxRx | Rx | Rx | TxRx | Rx | 1192 | 6 | "GOODBYE" | TxRx | TxRx | TxRx | TxRx | TxRx | TxRx | 1193 | | | | | | | | | 1194 | 8 | "ERROR" | Rx | Tx | Rx | Rx | TxRx | TxRx | 1195 | | | | | | | | | 1196 | 16 | "PUBLISH" | Tx | Rx | | | | | 1197 | 17 | "PUBLISHED" | Rx | Tx | | | | | 1198 | | | | | | | | | 1199 | 32 | "SUBSCRIBE" | | Rx | Tx | | | | 1200 | 33 | "SUBSCRIBED" | | Tx | Rx | | | | 1201 | 34 | "UNSUBSCRIBE" | | Rx | Tx | | | | 1202 | 35 | "UNSUBSCRIBED" | | Tx | Rx | | | | 1203 | 36 | "EVENT" | | Tx | Rx | | | | 1204 | | | | | | | | | 1205 | 48 | "CALL" | | | | Tx | Rx | | 1206 | 50 | "RESULT" | | | | Rx | Tx | | 1207 | | | | | | | | | 1208 | 64 | "REGISTER" | | | | | Rx | Tx | 1209 | 65 | "REGISTERED" | | | | | Tx | Rx | 1210 | 66 | "UNREGISTER" | | | | | Rx | Tx | 1211 | 67 | "UNREGISTERED" | | | | | Tx | Rx | 1212 | 68 | "INVOCATION" | | | | | Tx | Rx | 1213 | 70 | "YIELD" | | | | | Rx | Tx | 1214 +-----+----------------+------+------+------+------+-------+--------+ 1216 6.6. Extension Messages 1218 WAMP uses type codes from the core range [0, 255]. Implementations 1219 MAY define and use implementation specific messages with message type 1220 codes from the extension message range [256, 1023]. For example, a 1221 router MAY implement router-to-router communication by using 1222 extension messages. 1224 6.7. Empty Arguments and Keyword Arguments 1226 Implementations SHOULD avoid sending empty "Arguments" lists. 1228 E.g. a "CALL" message 1230 [CALL, Request|id, Options|dict, Procedure|uri, 1231 Arguments|list] 1233 where "Arguments == []" SHOULD be avoided, and instead 1235 [CALL, Request|id, Options|dict, Procedure|uri] 1237 SHOULD be sent. 1239 Implementations SHOULD avoid sending empty "ArgumentsKw" 1240 dictionaries. 1242 E.g. a "CALL" message 1244 [CALL, Request|id, Options|dict, Procedure|uri, 1245 Arguments|list, ArgumentsKw|dict] 1247 where "ArgumentsKw == {}" SHOULD be avoided, and instead 1249 [CALL, Request|id, Options|dict, Procedure|uri, 1250 Arguments|list] 1252 SHOULD be sent when "Arguments" is non-empty. 1254 7. Sessions 1256 The message flow between _Clients_ and _Routers_ for opening and 1257 closing WAMP sessions involves the following messages: 1259 1. "HELLO" 1261 2. "WELCOME" 1263 3. "ABORT" 1265 4. "GOODBYE" 1267 7.1. Session Establishment 1269 7.1.1. HELLO 1271 After the underlying transport has been established, the opening of a 1272 WAMP session is initiated by the _Client_ sending a "HELLO" message 1273 to the _Router_ 1275 [HELLO, Realm|uri, Details|dict] 1277 where 1279 o "Realm" is a string identifying the realm this session should 1280 attach to 1282 o "Details" is a dictionary that allows to provide additional 1283 opening information (see below). 1285 The "HELLO" message MUST be the very first message sent by the 1286 _Client_ after the transport has been established. 1288 In the WAMP Basic Profile without session authentication the _Router_ 1289 will reply with a "WELCOME" or "ABORT" message. 1291 ,------. ,------. 1292 |Client| |Router| 1293 `--+---' `--+---' 1294 | HELLO | 1295 | ----------------> 1296 | | 1297 | WELCOME | 1298 | <---------------- 1299 ,--+---. ,--+---. 1300 |Client| |Router| 1301 `------' `------' 1303 A WAMP session starts its lifetime when the _Router_ has sent a 1304 "WELCOME" message to the _Client_, and ends when the underlying 1305 transport closes or when the session is closed explicitly by either 1306 peer sending the "GOODBYE" message (see below). 1308 It is a protocol error to receive a second "HELLO" message during the 1309 lifetime of the session and the _Peer_ must fail the session if that 1310 happens. 1312 7.1.1.1. Client: Role and Feature Announcement 1314 WAMP uses _Role & Feature announcement_ instead of _protocol 1315 versioning_ to allow 1317 o implementations only supporting subsets of functionality 1319 o future extensibility 1321 A _Client_ must announce the *roles* it supports via 1322 "Hello.Details.roles|dict", with a key mapping to a 1323 "Hello.Details.roles.|dict" where "" can be: 1325 o "publisher" 1327 o "subscriber" 1329 o "caller" 1330 o "callee" 1332 A _Client_ can support any combination of the above roles but must 1333 support at least one role. 1335 The "|dict" is a dictionary describing *features* supported by 1336 the peer for that role. 1338 This MUST be empty for WAMP Basic Profile implementations, and MUST 1339 be used by implementations implementing parts of the Advanced Profile 1340 to list the specific set of features they support. 1342 _Example: A Client that implements the Publisher and Subscriber roles 1343 of the WAMP Basic Profile._ 1345 [1, "somerealm", { 1346 "roles": { 1347 "publisher": {}, 1348 "subscriber": {} 1349 } 1350 }] 1352 7.1.2. WELCOME 1354 A _Router_ completes the opening of a WAMP session by sending a 1355 "WELCOME" reply message to the _Client_. 1357 [WELCOME, Session|id, Details|dict] 1359 where 1361 o "Session" MUST be a randomly generated ID specific to the WAMP 1362 session. This applies for the lifetime of the session. 1364 o "Details" is a dictionary that allows to provide additional 1365 information regarding the open session (see below). 1367 In the WAMP Basic Profile without session authentication, a "WELCOME" 1368 message MUST be the first message sent by the _Router_, directly in 1369 response to a "HELLO" message received from the _Client_. Extensions 1370 in the Advanced Profile MAY include intermediate steps and messages 1371 for authentication. 1373 Note. The behavior if a requested "Realm" does not presently 1374 exist is router-specific. A router may e.g. automatically create 1375 the realm, or deny the establishment of the session with a "ABORT" 1376 reply message. 1378 7.1.2.1. Router: Role and Feature Announcement 1380 Similar to a _Client_ announcing _Roles_ and _Features_ supported in 1381 the `"HELLO" message, a _Router_ announces its supported _Roles_ and 1382 _Features_ in the "WELCOME" message. 1384 A _Router_ MUST announce the *roles* it supports via 1385 "Welcome.Details.roles|dict", with a key mapping to a 1386 "Welcome.Details.roles.|dict" where "" can be: 1388 o "broker" 1390 o "dealer" 1392 A _Router_ must support at least one role, and MAY support both 1393 roles. 1395 The "|dict" is a dictionary describing *features* supported by 1396 the peer for that role. With WAMP Basic Profile implementations, 1397 this MUST be empty, but MUST be used by implementations implementing 1398 parts of the Advanced Profile to list the specific set of features 1399 they support 1401 _Example: A Router implementing the Broker role of the WAMP Basic 1402 Profile._ 1404 [2, 9129137332, { 1405 "roles": { 1406 "broker": {} 1407 } 1408 }] 1410 7.1.3. ABORT 1412 Both the _Router_ and the _Client_ may abort the opening of a WAMP 1413 session by sending an "ABORT" message. 1415 [ABORT, Details|dict, Reason|uri] 1417 where 1419 o "Reason" MUST be an URI. 1421 o "Details" MUST be a dictionary that allows to provide additional, 1422 optional closing information (see below). 1424 No response to an "ABORT" message is expected. 1426 ,------. ,------. 1427 |Client| |Router| 1428 `--+---' `--+---' 1429 | HELLO | 1430 | ----------------> 1431 | | 1432 | ABORT | 1433 | <---------------- 1434 ,--+---. ,--+---. 1435 |Client| |Router| 1436 `------' `------' 1438 _Example_ 1440 [3, {"message": "The realm does not exist."}, 1441 "wamp.error.no_such_realm"] 1443 7.2. Session Closing 1445 A WAMP session starts its lifetime with the _Router_ sending a 1446 "WELCOME" message to the _Client_ and ends when the underlying 1447 transport disappears or when the WAMP session is closed explicitly by 1448 a "GOODBYE" message sent by one _Peer_ and a "GOODBYE" message sent 1449 from the other _Peer_ in response. 1451 [GOODBYE, Details|dict, Reason|uri] 1453 where 1455 o "Reason" MUST be an URI. 1457 o "Details" MUST be a dictionary that allows to provide additional, 1458 optional closing information (see below). 1460 ,------. ,------. 1461 |Client| |Router| 1462 `--+---' `--+---' 1463 | GOODBYE | 1464 | ----------------> 1465 | | 1466 | GOODBYE | 1467 | <---------------- 1468 ,--+---. ,--+---. 1469 |Client| |Router| 1470 `------' `------' 1471 ,------. ,------. 1472 |Client| |Router| 1473 `--+---' `--+---' 1474 | GOODBYE | 1475 | <---------------- 1476 | | 1477 | GOODBYE | 1478 | ----------------> 1479 ,--+---. ,--+---. 1480 |Client| |Router| 1481 `------' `------' 1483 _Example_. One _Peer_ initiates closing 1485 [6, {"message": "The host is shutting down now."}, 1486 "wamp.error.system_shutdown"] 1488 and the other peer replies 1490 [6, {}, "wamp.error.goodbye_and_out"] 1492 _Example_. One _Peer_ initiates closing 1494 [6, {}, "wamp.error.close_realm"] 1496 and the other peer replies 1498 [6, {}, "wamp.error.goodbye_and_out"] 1500 7.2.1. Difference between ABORT and GOODBYE 1502 The differences between "ABORT" and "GOODBYE" messages are: 1504 1. "ABORT" gets sent only _before_ a _Session_ is established, while 1505 "GOODBYE" is sent only _after_ a _Session_ is already 1506 established. 1508 2. "ABORT" is never replied to by a _Peer_, whereas "GOODBYE" must 1509 be replied to by the receiving _Peer_ 1511 Though "ABORT" and "GOODBYE" are structurally identical, using 1512 different message types serves to reduce overloaded meaning of 1513 messages and simplify message handling code. 1515 7.3. Agent Identification 1517 When a software agent operates in a network protocol, it often 1518 identifies itself, its application type, operating system, software 1519 vendor, or software revision, by submitting a characteristic 1520 identification string to its operating peer. 1522 Similar to what browsers do with the "User-Agent" HTTP header, both 1523 the "HELLO" and the "WELCOME" message MAY disclose the WAMP 1524 implementation in use to its peer: 1526 HELLO.Details.agent|string 1528 and 1530 WELCOME.Details.agent|string 1532 _Example: A Client "HELLO" message._ 1534 [1, "somerealm", { 1535 "agent": "AutobahnJS-0.9.14", 1536 "roles": { 1537 "subscriber": {}, 1538 "publisher": {} 1539 } 1540 }] 1542 _Example: A Router "WELCOME" message._ 1544 [2, 9129137332, { 1545 "agent": "Crossbar.io-0.10.11", 1546 "roles": { 1547 "broker": {} 1548 } 1549 }] 1551 8. Publish and Subscribe 1553 All of the following features for Publish & Subscribe are mandatory 1554 for WAMP Basic Profile implementations supporting the respective 1555 roles, i.e. _Publisher_, _Subscriber_ and _Dealer_. 1557 8.1. Subscribing and Unsubscribing 1559 The message flow between _Clients_ implementing the role of 1560 _Subscriber_ and _Routers_ implementing the role of _Broker_ for 1561 subscribing and unsubscribing involves the following messages: 1563 1. "SUBSCRIBE" 1565 2. "SUBSCRIBED" 1567 3. "UNSUBSCRIBE" 1569 4. "UNSUBSCRIBED" 1571 5. "ERROR" 1573 ,---------. ,------. ,----------. 1574 |Publisher| |Broker| |Subscriber| 1575 `----+----' `--+---' `----+-----' 1576 | | | 1577 | | | 1578 | | SUBSCRIBE | 1579 | | <--------------------- 1580 | | | 1581 | | SUBSCRIBED or ERROR | 1582 | | ---------------------> 1583 | | | 1584 | | | 1585 | | | 1586 | | | 1587 | | UNSUBSCRIBE | 1588 | | <--------------------- 1589 | | | 1590 | | UNSUBSCRIBED or ERROR| 1591 | | ---------------------> 1592 ,----+----. ,--+---. ,----+-----. 1593 |Publisher| |Broker| |Subscriber| 1594 `---------' `------' `----------' 1596 A _Subscriber_ may subscribe to zero, one or more topics, and a 1597 _Publisher_ publishes to topics without knowledge of subscribers. 1599 Upon subscribing to a topic via the "SUBSCRIBE" message, a 1600 _Subscriber_ will receive any future events published to the 1601 respective topic by _Publishers_, and will receive those events 1602 asynchronously. 1604 A subscription lasts for the duration of a session, unless a 1605 _Subscriber_ opts out from a previously established subscription via 1606 the "UNSUBSCRIBE" message. 1608 A _Subscriber_ may have more than one event handler attached to 1609 the same subscription. This can be implemented in different ways: 1610 a) a _Subscriber_ can recognize itself that it is already 1611 subscribed and just attach another handler to the subscription for 1612 incoming events, b) or it can send a new "SUBSCRIBE" message to 1613 broker (as it would be first) and upon receiving a 1614 "SUBSCRIBED.Subscription|id" it already knows about, attach the 1615 handler to the existing subscription 1617 8.1.1. SUBSCRIBE 1619 A _Subscriber_ communicates its interest in a topic to a _Broker_ by 1620 sending a "SUBSCRIBE" message: 1622 [SUBSCRIBE, Request|id, Options|dict, Topic|uri] 1624 where 1626 o "Request" MUST be a random, ephemeral ID chosen by the 1627 _Subscriber_ and used to correlate the _Broker's_ response with 1628 the request. 1630 o "Options" MUST be a dictionary that allows to provide additional 1631 subscription request details in a extensible way. This is 1632 described further below. 1634 o "Topic" is the topic the _Subscriber_ wants to subscribe to and 1635 MUST be an URI. 1637 _Example_ 1639 [32, 713845233, {}, "com.myapp.mytopic1"] 1641 A _Broker_, receiving a "SUBSCRIBE" message, can fullfill or reject 1642 the subscription, so it answers with "SUBSCRIBED" or "ERROR" 1643 messages. 1645 8.1.2. SUBSCRIBED 1647 If the _Broker_ is able to fulfill and allow the subscription, it 1648 answers by sending a "SUBSCRIBED" message to the _Subscriber_ 1650 [SUBSCRIBED, SUBSCRIBE.Request|id, Subscription|id] 1652 where 1654 o "SUBSCRIBE.Request" MUST be the ID from the original request. 1656 o "Subscription" MUST be an ID chosen by the _Broker_ for the 1657 subscription. 1659 _Example_ 1661 [33, 713845233, 5512315355] 1663 Note. The "Subscription" ID chosen by the broker need not be 1664 unique to the subscription of a single _Subscriber_, but may be 1665 assigned to the "Topic", or the combination of the "Topic" and 1666 some or all "Options", such as the topic pattern matching method 1667 to be used. Then this ID may be sent to all _Subscribers_ for the 1668 "Topic" or "Topic" / "Options" combination. This allows the 1669 _Broker_ to serialize an event to be delivered only once for all 1670 actual receivers of the event. 1672 In case of receiving a "SUBSCRIBE" message from the same 1673 _Subscriber_ and to already subscribed topic, _Broker_ should 1674 answer with "SUBSCRIBED" message, containing the existing 1675 "Subscription|id". 1677 8.1.3. Subscribe ERROR 1679 When the request for subscription cannot be fulfilled by the 1680 _Broker_, the _Broker_ sends back an "ERROR" message to the 1681 _Subscriber_ 1683 [ERROR, SUBSCRIBE, SUBSCRIBE.Request|id, Details|dict, 1684 Error|uri] 1686 where 1688 o "SUBSCRIBE.Request" MUST be the ID from the original request. 1690 o "Error" MUST be an URI that gives the error of why the request 1691 could not be fulfilled. 1693 _Example_ 1695 [8, 32, 713845233, {}, "wamp.error.not_authorized"] 1697 8.1.4. UNSUBSCRIBE 1699 When a _Subscriber_ is no longer interested in receiving events for a 1700 subscription it sends an "UNSUBSCRIBE" message 1702 [UNSUBSCRIBE, Request|id, SUBSCRIBED.Subscription|id] 1704 where 1705 o "Request" MUST be a random, ephemeral ID chosen by the 1706 _Subscriber_ and used to correlate the _Broker's_ response with 1707 the request. 1709 o "SUBSCRIBED.Subscription" MUST be the ID for the subscription to 1710 unsubscribe from, originally handed out by the _Broker_ to the 1711 _Subscriber_. 1713 _Example_ 1715 [34, 85346237, 5512315355] 1717 8.1.5. UNSUBSCRIBED 1719 Upon successful unsubscription, the _Broker_ sends an "UNSUBSCRIBED" 1720 message to the _Subscriber_ 1722 [UNSUBSCRIBED, UNSUBSCRIBE.Request|id] 1724 where 1726 o "UNSUBSCRIBE.Request" MUST be the ID from the original request. 1728 _Example_ 1730 [35, 85346237] 1732 8.1.6. Unsubscribe ERROR 1734 When the request fails, the _Broker_ sends an "ERROR" 1736 [ERROR, UNSUBSCRIBE, UNSUBSCRIBE.Request|id, Details|dict, 1737 Error|uri] 1739 where 1741 o "UNSUBSCRIBE.Request" MUST be the ID from the original request. 1743 o "Error" MUST be an URI that gives the error of why the request 1744 could not be fulfilled. 1746 _Example_ 1748 [8, 34, 85346237, {}, "wamp.error.no_such_subscription"] 1750 8.2. Publishing and Events 1752 The message flow between _Publishers_, a _Broker_ and _Subscribers_ 1753 for publishing to topics and dispatching events involves the 1754 following messages: 1756 1. "PUBLISH" 1758 2. "PUBLISHED" 1760 3. "EVENT" 1762 4. "ERROR" 1764 ,---------. ,------. ,----------. 1765 |Publisher| |Broker| |Subscriber| 1766 `----+----' `--+---' `----+-----' 1767 | PUBLISH | | 1768 |------------------> | 1769 | | | 1770 |PUBLISHED or ERROR| | 1771 |<------------------ | 1772 | | | 1773 | | EVENT | 1774 | | ------------------> 1775 ,----+----. ,--+---. ,----+-----. 1776 |Publisher| |Broker| |Subscriber| 1777 `---------' `------' `----------' 1779 8.2.1. PUBLISH 1781 When a _Publisher_ requests to publish an event to some topic, it 1782 sends a "PUBLISH" message to a _Broker_: 1784 [PUBLISH, Request|id, Options|dict, Topic|uri] 1786 or 1788 [PUBLISH, Request|id, Options|dict, Topic|uri, Arguments|list] 1790 or 1792 [PUBLISH, Request|id, Options|dict, Topic|uri, Arguments|list, 1793 ArgumentsKw|dict] 1795 where 1796 o "Request" is a random, ephemeral ID chosen by the _Publisher_ and 1797 used to correlate the _Broker's_ response with the request. 1799 o "Options" is a dictionary that allows to provide additional 1800 publication request details in an extensible way. This is 1801 described further below. 1803 o "Topic" is the topic published to. 1805 o "Arguments" is a list of application-level event payload elements. 1806 The list may be of zero length. 1808 o "ArgumentsKw" is an optional dictionary containing application- 1809 level event payload, provided as keyword arguments. The 1810 dictionary may be empty. 1812 If the _Broker_ is able to fulfill and allowing the publication, the 1813 _Broker_ will send the event to all current _Subscribers_ of the 1814 topic of the published event. 1816 By default, publications are unacknowledged, and the _Broker_ will 1817 not respond, whether the publication was successful indeed or not. 1818 This behavior can be changed with the option 1819 "PUBLISH.Options.acknowledge|bool" (see below). 1821 _Example_ 1823 [16, 239714735, {}, "com.myapp.mytopic1"] 1825 _Example_ 1827 [16, 239714735, {}, "com.myapp.mytopic1", ["Hello, world!"]] 1829 _Example_ 1831 [16, 239714735, {}, "com.myapp.mytopic1", [], {"color": "orange", 1832 "sizes": [23, 42, 7]}] 1834 8.2.2. PUBLISHED 1836 If the _Broker_ is able to fulfill and allowing the publication, and 1837 "PUBLISH.Options.acknowledge == true", the _Broker_ replies by 1838 sending a "PUBLISHED" message to the _Publisher_: 1840 [PUBLISHED, PUBLISH.Request|id, Publication|id] 1842 where 1843 o "PUBLISH.Request" is the ID from the original publication request. 1845 o "Publication" is a ID chosen by the Broker for the publication. 1847 _Example_ 1849 [17, 239714735, 4429313566] 1851 8.2.3. Publish ERROR 1853 When the request for publication cannot be fulfilled by the _Broker_, 1854 and "PUBLISH.Options.acknowledge == true", the _Broker_ sends back an 1855 "ERROR" message to the _Publisher_ 1857 [ERROR, PUBLISH, PUBLISH.Request|id, Details|dict, Error|uri] 1859 where 1861 o "PUBLISH.Request" is the ID from the original publication request. 1863 o "Error" is an URI that gives the error of why the request could 1864 not be fulfilled. 1866 _Example_ 1868 [8, 16, 239714735, {}, "wamp.error.not_authorized"] 1870 8.2.4. EVENT 1872 When a publication is successful and a _Broker_ dispatches the event, 1873 it determines a list of receivers for the event based on 1874 _Subscribers_ for the topic published to and, possibly, other 1875 information in the event. 1877 Note that the _Publisher_ of an event will never receive the 1878 published event even if the _Publisher_ is also a _Subscriber_ of the 1879 topic published to. 1881 The Advanced Profile provides options for more detailed control 1882 over publication. 1884 When a _Subscriber_ is deemed to be a receiver, the _Broker_ sends 1885 the _Subscriber_ an "EVENT" message: 1887 [EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id, 1888 Details|dict] 1890 or 1892 [EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id, 1893 Details|dict, PUBLISH.Arguments|list] 1895 or 1897 [EVENT, SUBSCRIBED.Subscription|id, PUBLISHED.Publication|id, 1898 Details|dict, PUBLISH.Arguments|list, PUBLISH.ArgumentKw|dict] 1900 where 1902 o "SUBSCRIBED.Subscription" is the ID for the subscription under 1903 which the _Subscriber_ receives the event - the ID for the 1904 subscription originally handed out by the _Broker_ to the 1905 _Subscriber_. 1907 o "PUBLISHED.Publication" is the ID of the publication of the 1908 published event. 1910 o "Details" is a dictionary that allows the _Broker_ to provide 1911 additional event details in a extensible way. This is described 1912 further below. 1914 o "PUBLISH.Arguments" is the application-level event payload that 1915 was provided with the original publication request. 1917 o "PUBLISH.ArgumentKw" is the application-level event payload that 1918 was provided with the original publication request. 1920 _Example_ 1922 [36, 5512315355, 4429313566, {}] 1924 _Example_ 1926 [36, 5512315355, 4429313566, {}, ["Hello, world!"]] 1928 _Example_ 1930 [36, 5512315355, 4429313566, {}, [], {"color": "orange", 1931 "sizes": [23, 42, 7]}] 1933 9. Remote Procedure Calls 1935 All of the following features for Remote Procedure Calls are 1936 mandatory for WAMP Basic Profile implementations supporting the 1937 respective roles. 1939 9.1. Registering and Unregistering 1941 The message flow between _Callees_ and a _Dealer_ for registering and 1942 unregistering endpoints to be called over RPC involves the following 1943 messages: 1945 1. "REGISTER" 1947 2. "REGISTERED" 1949 3. "UNREGISTER" 1951 4. "UNREGISTERED" 1953 5. "ERROR" 1955 ,------. ,------. ,------. 1956 |Caller| |Dealer| |Callee| 1957 `--+---' `--+---' `--+---' 1958 | | | 1959 | | | 1960 | | REGISTER | 1961 | | <--------------------- 1962 | | | 1963 | | REGISTERED or ERROR | 1964 | | ---------------------> 1965 | | | 1966 | | | 1967 | | | 1968 | | | 1969 | | | 1970 | | UNREGISTER | 1971 | | <--------------------- 1972 | | | 1973 | | UNREGISTERED or ERROR| 1974 | | ---------------------> 1975 ,--+---. ,--+---. ,--+---. 1976 |Caller| |Dealer| |Callee| 1977 `------' `------' `------' 1979 9.1.1. REGISTER 1981 A _Callee_ announces the availability of an endpoint implementing a 1982 procedure with a _Dealer_ by sending a "REGISTER" message: 1984 [REGISTER, Request|id, Options|dict, Procedure|uri] 1986 where 1987 o "Request" is a random, ephemeral ID chosen by the _Callee_ and 1988 used to correlate the _Dealer's_ response with the request. 1990 o "Options" is a dictionary that allows to provide additional 1991 registration request details in a extensible way. This is 1992 described further below. 1994 o "Procedure"is the procedure the _Callee_ wants to register 1996 _Example_ 1998 [64, 25349185, {}, "com.myapp.myprocedure1"] 2000 9.1.2. REGISTERED 2002 If the _Dealer_ is able to fulfill and allowing the registration, it 2003 answers by sending a "REGISTERED" message to the "Callee": 2005 [REGISTERED, REGISTER.Request|id, Registration|id] 2007 where 2009 o "REGISTER.Request" is the ID from the original request. 2011 o "Registration" is an ID chosen by the _Dealer_ for the 2012 registration. 2014 _Example_ 2016 [65, 25349185, 2103333224] 2018 9.1.3. Register ERROR 2020 When the request for registration cannot be fulfilled by the 2021 _Dealer_, the _Dealer_ sends back an "ERROR" message to the _Callee_: 2023 [ERROR, REGISTER, REGISTER.Request|id, Details|dict, Error|uri] 2025 where 2027 o "REGISTER.Request" is the ID from the original request. 2029 o "Error" is an URI that gives the error of why the request could 2030 not be fulfilled. 2032 _Example_ 2034 [8, 64, 25349185, {}, "wamp.error.procedure_already_exists"] 2036 9.1.4. UNREGISTER 2038 When a _Callee_ is no longer willing to provide an implementation of 2039 the registered procedure, it sends an "UNREGISTER" message to the 2040 _Dealer_: 2042 [UNREGISTER, Request|id, REGISTERED.Registration|id] 2044 where 2046 o "Request" is a random, ephemeral ID chosen by the _Callee_ and 2047 used to correlate the _Dealer's_ response with the request. 2049 o "REGISTERED.Registration" is the ID for the registration to 2050 revoke, originally handed out by the _Dealer_ to the _Callee_. 2052 _Example_ 2054 [66, 788923562, 2103333224] 2056 9.1.5. UNREGISTERED 2058 Upon successful unregistration, the _Dealer_ sends an "UNREGISTERED" 2059 message to the _Callee_: 2061 [UNREGISTERED, UNREGISTER.Request|id] 2063 where 2065 o "UNREGISTER.Request" is the ID from the original request. 2067 _Example_ 2069 [67, 788923562] 2071 9.1.6. Unregister ERROR 2073 When the unregistration request fails, the _Dealer_ sends an "ERROR" 2074 message: 2076 [ERROR, UNREGISTER, UNREGISTER.Request|id, Details|dict, 2077 Error|uri] 2079 where 2081 o "UNREGISTER.Request" is the ID from the original request. 2083 o "Error" is an URI that gives the error of why the request could 2084 not be fulfilled. 2086 _Example_ 2088 [8, 66, 788923562, {}, "wamp.error.no_such_registration"] 2090 9.2. Calling and Invocations 2092 The message flow between _Callers_, a _Dealer_ and _Callees_ for 2093 calling procedures and invoking endpoints involves the following 2094 messages: 2096 1. "CALL" 2098 2. "RESULT" 2100 3. "INVOCATION" 2102 4. "YIELD" 2104 5. "ERROR" 2106 ,------. ,------. ,------. 2107 |Caller| |Dealer| |Callee| 2108 `--+---' `--+---' `--+---' 2109 | CALL | | 2110 | ----------------> | 2111 | | | 2112 | | INVOCATION | 2113 | | ----------------> 2114 | | | 2115 | | YIELD or ERROR | 2116 | | <---------------- 2117 | | | 2118 | RESULT or ERROR | | 2119 | <---------------- | 2120 ,--+---. ,--+---. ,--+---. 2121 |Caller| |Dealer| |Callee| 2122 `------' `------' `------' 2124 The execution of remote procedure calls is asynchronous, and there 2125 may be more than one call outstanding. A call is called outstanding 2126 (from the point of view of the _Caller_), when a (final) result or 2127 error has not yet been received by the _Caller_. 2129 9.2.1. CALL 2131 When a _Caller_ wishes to call a remote procedure, it sends a "CALL" 2132 message to a _Dealer_: 2134 [CALL, Request|id, Options|dict, Procedure|uri] 2136 or 2138 [CALL, Request|id, Options|dict, Procedure|uri, Arguments|list] 2140 or 2142 [CALL, Request|id, Options|dict, Procedure|uri, Arguments|list, 2143 ArgumentsKw|dict] 2145 where 2147 o "Request" is a random, ephemeral ID chosen by the _Caller_ and 2148 used to correlate the _Dealer's_ response with the request. 2150 o "Options" is a dictionary that allows to provide additional call 2151 request details in an extensible way. This is described further 2152 below. 2154 o "Procedure" is the URI of the procedure to be called. 2156 o "Arguments" is a list of positional call arguments (each of 2157 arbitrary type). The list may be of zero length. 2159 o "ArgumentsKw" is a dictionary of keyword call arguments (each of 2160 arbitrary type). The dictionary may be empty. 2162 _Example_ 2164 [48, 7814135, {}, "com.myapp.ping"] 2166 _Example_ 2168 [48, 7814135, {}, "com.myapp.echo", ["Hello, world!"]] 2170 _Example_ 2172 [48, 7814135, {}, "com.myapp.add2", [23, 7]] 2174 _Example_ 2176 [48, 7814135, {}, "com.myapp.user.new", ["johnny"], 2177 {"firstname": "John", "surname": "Doe"}] 2179 9.2.2. INVOCATION 2181 If the _Dealer_ is able to fulfill (mediate) the call and it allows 2182 the call, it sends a "INVOCATION" message to the respective _Callee_ 2183 implementing the procedure: 2185 [INVOCATION, Request|id, REGISTERED.Registration|id, 2186 Details|dict] 2188 or 2190 [INVOCATION, Request|id, REGISTERED.Registration|id, 2191 Details|dict, CALL.Arguments|list] 2193 or 2195 [INVOCATION, Request|id, REGISTERED.Registration|id, 2196 Details|dict, CALL.Arguments|list, CALL.ArgumentsKw|dict] 2198 where 2200 o "Request" is a random, ephemeral ID chosen by the _Dealer_ and 2201 used to correlate the _Callee's_ response with the request. 2203 o "REGISTERED.Registration" is the registration ID under which the 2204 procedure was registered at the _Dealer_. 2206 o "Details" is a dictionary that allows to provide additional 2207 invocation request details in an extensible way. This is 2208 described further below. 2210 o "CALL.Arguments" is the original list of positional call arguments 2211 as provided by the _Caller_. 2213 o "CALL.ArgumentsKw" is the original dictionary of keyword call 2214 arguments as provided by the _Caller_. 2216 _Example_ 2218 [68, 6131533, 9823526, {}] 2220 _Example_ 2222 [68, 6131533, 9823527, {}, ["Hello, world!"]] 2224 _Example_ 2226 [68, 6131533, 9823528, {}, [23, 7]] 2228 _Example_ 2230 [68, 6131533, 9823529, {}, ["johnny"], {"firstname": "John", 2231 "surname": "Doe"}] 2233 9.2.3. YIELD 2235 If the _Callee_ is able to successfully process and finish the 2236 execution of the call, it answers by sending a "YIELD" message to the 2237 _Dealer_: 2239 [YIELD, INVOCATION.Request|id, Options|dict] 2241 or 2243 [YIELD, INVOCATION.Request|id, Options|dict, Arguments|list] 2245 or 2247 [YIELD, INVOCATION.Request|id, Options|dict, Arguments|list, 2248 ArgumentsKw|dict] 2250 where 2252 o "INVOCATION.Request" is the ID from the original invocation 2253 request. 2255 o "Options"is a dictionary that allows to provide additional 2256 options. 2258 o "Arguments" is a list of positional result elements (each of 2259 arbitrary type). The list may be of zero length. 2261 o "ArgumentsKw" is a dictionary of keyword result elements (each of 2262 arbitrary type). The dictionary may be empty. 2264 _Example_ 2266 [70, 6131533, {}] 2268 _Example_ 2270 [70, 6131533, {}, ["Hello, world!"]] 2272 _Example_ 2274 [70, 6131533, {}, [30]] 2276 _Example_ 2278 [70, 6131533, {}, [], {"userid": 123, "karma": 10}] 2280 9.2.4. RESULT 2282 The _Dealer_ will then send a "RESULT" message to the original 2283 _Caller_: 2285 [RESULT, CALL.Request|id, Details|dict] 2287 or 2289 [RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list] 2291 or 2293 [RESULT, CALL.Request|id, Details|dict, YIELD.Arguments|list, 2294 YIELD.ArgumentsKw|dict] 2296 where 2298 o "CALL.Request" is the ID from the original call request. 2300 o "Details" is a dictionary of additional details. 2302 o "YIELD.Arguments" is the original list of positional result 2303 elements as returned by the _Callee_. 2305 o "YIELD.ArgumentsKw" is the original dictionary of keyword result 2306 elements as returned by the _Callee_. 2308 _Example_ 2310 [50, 7814135, {}] 2312 _Example_ 2314 [50, 7814135, {}, ["Hello, world!"]] 2316 _Example_ 2318 [50, 7814135, {}, [30]] 2320 _Example_ 2322 [50, 7814135, {}, [], {"userid": 123, "karma": 10}] 2324 9.2.5. Invocation ERROR 2326 If the _Callee_ is unable to process or finish the execution of the 2327 call, or the application code implementing the procedure raises an 2328 exception or otherwise runs into an error, the _Callee_ sends an 2329 "ERROR" message to the _Dealer_: 2331 [ERROR, INVOCATION, INVOCATION.Request|id, Details|dict, 2332 Error|uri] 2334 or 2336 [ERROR, INVOCATION, INVOCATION.Request|id, Details|dict, 2337 Error|uri, Arguments|list] 2339 or 2341 [ERROR, INVOCATION, INVOCATION.Request|id, Details|dict, 2342 Error|uri, Arguments|list, ArgumentsKw|dict] 2344 where 2346 o "INVOCATION.Request" is the ID from the original "INVOCATION" 2347 request previously sent by the _Dealer_ to the _Callee_. 2349 o "Details" is a dictionary with additional error details. 2351 o "Error" is an URI that identifies the error of why the request 2352 could not be fulfilled. 2354 o "Arguments" is a list containing arbitrary, application defined, 2355 positional error information. This will be forwarded by the 2356 _Dealer_ to the _Caller_ that initiated the call. 2358 o "ArgumentsKw" is a dictionary containing arbitrary, application 2359 defined, keyword-based error information. This will be forwarded 2360 by the _Dealer_ to the _Caller_ that initiated the call. 2362 _Example_ 2364 [8, 68, 6131533, {}, "com.myapp.error.object_write_protected", 2365 ["Object is write protected."], {"severity": 3}] 2367 9.2.6. Call ERROR 2369 The _Dealer_ will then send a "ERROR" message to the original 2370 _Caller_: 2372 [ERROR, CALL, CALL.Request|id, Details|dict, Error|uri] 2374 or 2376 [ERROR, CALL, CALL.Request|id, Details|dict, Error|uri, 2377 Arguments|list] 2379 or 2381 [ERROR, CALL, CALL.Request|id, Details|dict, Error|uri, 2382 Arguments|list, ArgumentsKw|dict] 2384 where 2386 o "CALL.Request" is the ID from the original "CALL" request sent by 2387 the _Caller_ to the _Dealer_. 2389 o "Details" is a dictionary with additional error details. 2391 o "Error" is an URI identifying the type of error as returned by the 2392 _Callee_ to the _Dealer_. 2394 o "Arguments" is a list containing the original error payload list 2395 as returned by the _Callee_ to the _Dealer_. 2397 o "ArgumentsKw" is a dictionary containing the original error 2398 payload dictionary as returned by the _Callee_ to the _Dealer_ 2400 _Example_ 2402 [8, 48, 7814135, {}, "com.myapp.error.object_write_protected", 2403 ["Object is write protected."], {"severity": 3}] 2405 If the original call already failed at the _Dealer_ *before* the call 2406 would have been forwarded to any _Callee_, the _Dealer_ will send an 2407 "ERROR" message to the _Caller_: 2409 [ERROR, CALL, CALL.Request|id, Details|dict, Error|uri] 2411 _Example_ 2413 [8, 48, 7814135, {}, "wamp.error.no_such_procedure"] 2415 10. Predefined URIs 2417 WAMP pre-defines the following error URIs for the basic and for the 2418 advanced profile. WAMP peers MUST use only the defined error 2419 messages. 2421 10.1. Basic Profile 2423 10.1.1. Incorrect URIs 2425 When a _Peer_ provides an incorrect URI for any URI-based attribute 2426 of a WAMP message (e.g. realm, topic), then the other _Peer_ MUST 2427 respond with an "ERROR" message and give the following _Error URI_: 2429 wamp.error.invalid_uri 2431 10.1.2. Interaction 2433 _Peer_ provided an incorrect URI for any URI-based attribute of WAMP 2434 message, such as realm, topic or procedure 2436 wamp.error.invalid_uri 2438 A _Dealer_ could not perform a call, since no procedure is currently 2439 registered under the given URI. 2441 wamp.error.no_such_procedure 2443 A procedure could not be registered, since a procedure with the given 2444 URI is already registered. 2446 wamp.error.procedure_already_exists 2448 A _Dealer_ could not perform an unregister, since the given 2449 registration is not active. 2451 wamp.error.no_such_registration 2453 A _Broker_ could not perform an unsubscribe, since the given 2454 subscription is not active. 2456 wamp.error.no_such_subscription 2458 A call failed since the given argument types or values are not 2459 acceptable to the called procedure. In this case the _Callee_ may 2460 throw this error. Alternatively a _Router_ may throw this error if 2461 it performed _payload validation_ of a call, call result, call error 2462 or publish, and the payload did not conform to the requirements. 2464 wamp.error.invalid_argument 2466 10.1.3. Session Close 2468 The _Peer_ is shutting down completely - used as a "GOODBYE" (or 2469 "ABORT") reason. 2471 wamp.error.system_shutdown 2473 The _Peer_ want to leave the realm - used as a "GOODBYE" reason. 2475 wamp.error.close_realm 2477 A _Peer_ acknowledges ending of a session - used as a "GOODBYE" reply 2478 reason. 2480 wamp.error.goodbye_and_out 2482 10.1.4. Authorization 2484 A join, call, register, publish or subscribe failed, since the _Peer_ 2485 is not authorized to perform the operation. 2487 wamp.error.not_authorized 2489 A _Dealer_ or _Broker_ could not determine if the _Peer_ is 2490 authorized to perform a join, call, register, publish or subscribe, 2491 since the authorization operation _itself_ failed. E.g. a custom 2492 authorizer did run into an error. 2494 wamp.error.authorization_failed 2496 _Peer_ wanted to join a non-existing realm (and the _Router_ did not 2497 allow to auto-create the realm). 2499 wamp.error.no_such_realm 2501 A _Peer_ was to be authenticated under a Role that does not (or no 2502 longer) exists on the Router. For example, the _Peer_ was 2503 successfully authenticated, but the Role configured does not exists - 2504 hence there is some misconfiguration in the Router. 2506 wamp.error.no_such_role 2508 10.2. Advanced Profile 2510 uri_Dealer_ or _Callee_ canceled a call previously issued 2512 wamp.error.canceled 2514 A _Peer_ requested an interaction with an option that was disallowed 2515 by the _Router_ 2517 wamp.error.option_not_allowed 2519 A _Dealer_ could not perform a call, since a procedure with the given 2520 URI is registered, but _Callee Black- and Whitelisting_ and/or 2521 _Caller Exclusion_ lead to the exclusion of (any) _Callee_ providing 2522 the procedure. 2524 wamp.error.no_eligible_callee 2526 A _Router_ rejected client request to disclose its identity 2528 wamp.error.option_disallowed.disclose_me 2530 A _Router_ encountered a network failure 2532 wamp.error.network_failure 2534 11. Ordering Guarantees 2536 All WAMP implementations, in particular _Routers_ MUST support the 2537 following ordering guarantees. 2539 A WAMP Advanced Profile may provide applications options to relax 2540 ordering guarantees, in particular with distributed calls. 2542 11.1. Publish & Subscribe Ordering 2544 Regarding *Publish & Subscribe*, the ordering guarantees are as 2545 follows: 2547 If _Subscriber A_ is subscribed to both *Topic 1* and *Topic 2*, and 2548 _Publisher B_ first publishes an *Event 1* to *Topic 1* and then an 2549 *Event 2* to *Topic 2*, then _Subscriber A_ will first receive *Event 2550 1* and then *Event 2*. This also holds if *Topic 1* and *Topic 2* are 2551 identical. 2553 In other words, WAMP guarantees ordering of events between any given 2554 _pair_ of _Publisher_ and _Subscriber_. 2556 Further, if _Subscriber A_ subscribes to *Topic 1*, the "SUBSCRIBED" 2557 message will be sent by the _Broker_ to _Subscriber A_ before any 2558 "EVENT" message for *Topic 1*. 2560 There is no guarantee regarding the order of return for multiple 2561 subsequent subscribe requests. A subscribe request might require the 2562 _Broker_ to do a time-consuming lookup in some database, whereas 2563 another subscribe request second might be permissible immediately. 2565 11.2. Remote Procedure Call Ordering 2567 Regarding *Remote Procedure Calls*, the ordering guarantees are as 2568 follows: 2570 If _Callee A_ has registered endpoints for both *Procedure 1* and 2571 *Procedure 2*, and _Caller B_ first issues a *Call 1* to *Procedure 2572 1* and then a *Call 2* to *Procedure 2*, and both calls are routed to 2573 _Callee A_, then _Callee A_ will first receive an invocation 2574 corresponding to *Call 1* and then *Call 2*. This also holds if 2575 *Procedure 1* and *Procedure 2* are identical. 2577 In other words, WAMP guarantees ordering of invocations between any 2578 given _pair_ of _Caller_ and _Callee_. 2580 There are no guarantees on the order of call results and errors in 2581 relation to _different_ calls, since the execution of calls upon 2582 different invocations of endpoints in _Callees_ are running 2583 independently. A first call might require an expensive, long-running 2584 computation, whereas a second, subsequent call might finish 2585 immediately. 2587 Further, if _Callee A_ registers for *Procedure 1*, the "REGISTERED" 2588 message will be sent by _Dealer_ to _Callee A_ before any 2589 "INVOCATION" message for *Procedure 1*. 2591 There is no guarantee regarding the order of return for multiple 2592 subsequent register requests. A register request might require the 2593 _Broker_ to do a time-consuming lookup in some database, whereas 2594 another register request second might be permissible immediately. 2596 12. Security Model 2598 The following discusses the security model for the Basic Profile. 2599 Any changes or extensions to this for the Advanced Profile are 2600 discussed further on as part of the Advanced Profile definition. 2602 12.1. Transport Encryption and Integrity 2604 WAMP transports may provide (optional) transport-level encryption and 2605 integrity verification. If so, encryption and integrity is point-to- 2606 point: between a _Client_ and the _Router_ it is connected to. 2608 Transport-level encryption and integrity is solely at the transport- 2609 level and transparent to WAMP. WAMP itself deliberately does not 2610 specify any kind of transport-level encryption. 2612 Implementations that offer TCP based transport such as WAMP-over- 2613 WebSocket or WAMP-over-RawSocket SHOULD implement Transport Layer 2614 Security (TLS). 2616 WAMP deployments are encouraged to stick to a TLS-only policy with 2617 the TLS code and setup being hardened. 2619 Further, when a _Client_ connects to a _Router_ over a local-only 2620 transport such as Unix domain sockets, the integrity of the data 2621 transmitted is implicit (the OS kernel is trusted), and the privacy 2622 of the data transmitted can be assured using file system permissions 2623 (no one can tap a Unix domain socket without appropriate permissions 2624 or being root). 2626 12.2. Router Authentication 2628 To authenticate _Routers_ to _Clients_, deployments MUST run TLS and 2629 _Clients_ MUST verify the _Router_ server certificate presented. 2630 WAMP itself does not provide mechanisms to authenticate a _Router_ 2631 (only a _Client_). 2633 The verification of the _Router_ server certificate can happen 2635 1. against a certificate trust database that comes with the 2636 _Clients_ operating system 2638 2. against an issuing certificate/key hard-wired into the _Client_ 2640 3. by using new mechanisms like DNS-based Authentication of Named 2641 Enitities (DNSSEC)/TLSA 2643 Further, when a _Client_ connects to a _Router_ over a local-only 2644 transport such as Unix domain sockets, the file system permissions 2645 can be used to create implicit trust. E.g. if only the OS user under 2646 which the _Router_ runs has the permission to create a Unix domain 2647 socket under a specific path, _Clients_ connecting to that path can 2648 trust in the router authenticity. 2650 12.3. Client Authentication 2652 Authentication of a _Client_ to a _Router_ at the WAMP level is not 2653 part of the basic profile. 2655 When running over TLS, a _Router_ MAY authenticate a _Client_ at the 2656 transport level by doing a _client certificate based authentication_. 2658 12.3.1. Routers are trusted 2660 _Routers_ are _trusted_ by _Clients_. 2662 In particular, _Routers_ can read (and modify) any application 2663 payload transmitted in events, calls, call results and call errors 2664 (the "Arguments" or "ArgumentsKw" message fields). 2666 Hence, _Routers_ do not provide confidentiality with respect to 2667 application payload, and also do not provide authenticity or 2668 integrity of application payloads that could be verified by a 2669 receiving _Client_. 2671 _Routers_ need to read the application payloads in cases of automatic 2672 conversion between different serialization formats. 2674 Further, _Routers_ are trusted to *actually perform* routing as 2675 specified. E.g. a _Client_ that publishes an event has to trust a 2676 _Router_ that the event is actually dispatched to all (eligible) 2677 _Subscribers_ by the _Router_. 2679 A rogue _Router_ might deny normal routing operation without a 2680 _Client_ taking notice. 2682 13. Advanced Profile 2684 While implementations MUST implement the subset of the Basic Profile 2685 necessary for the particular set of WAMP roles they provide, they MAY 2686 implement any subset of features from the Advanced Profile. 2687 Implementers SHOULD implement the maximum of features possible 2688 considering the aims of an implementation. 2690 Note: Features listed here may be experimental or underspecced and 2691 yet unimplemented in any implementation. This is part of the 2692 specification is very much a work in progress. An approximate 2693 status of each feature is given at the beginning of the feature 2694 section. 2696 13.1. Messages 2698 The Advanced Profile defines the following additional messages which 2699 are explained in detail in separate sections. 2701 13.1.1. Message Definitions 2703 The following 4 additional message types MAY be used in the Advanced 2704 Profile. 2706 13.1.1.1. CHALLENGE 2708 The "CHALLENGE" message is used with certain Authentication Methods. 2709 During authenticated session establishment, a *Router* sends a 2710 challenge message. 2712 [CHALLENGE, AuthMethod|string, Extra|dict] 2714 13.1.1.2. AUTHENTICATE 2716 The "AUTHENTICATE" message is used with certain Authentication 2717 Methods. A *Client* having received a challenge is expected to 2718 respond by sending a signature or token. 2720 [AUTHENTICATE, Signature|string, Extra|dict] 2722 13.1.1.3. CANCEL 2724 The "CANCEL" message is used with the Call Canceling advanced 2725 feature. A _Caller_ can cancel and issued call actively by sending a 2726 cancel message to the _Dealer_. 2728 [CANCEL, CALL.Request|id, Options|dict] 2730 13.1.1.4. INTERRUPT 2732 The "INTERRUPT" message is used with the Call Canceling advanced 2733 feature. Upon receiving a cancel for a pending call, a _Dealer_ will 2734 issue an interrupt to the _Callee_. 2736 [INTERRUPT, INVOCATION.Request|id, Options|dict] 2738 13.1.2. Message Codes and Direction 2740 The following table list the message type code for *the OPTIONAL 2741 messages* defined in this part of the document and their direction 2742 between peer roles. 2744 +-----+----------------+-----+-----+------+------+-------+--------+ 2745 | Cod | Message | Pub | Brk | Subs | Calr | Dealr | Callee | 2746 +-----+----------------+-----+-----+------+------+-------+--------+ 2747 | 4 | "CHALLENGE" | Rx | Tx | Rx | Rx | Tx | Rx | 2748 | 5 | "AUTHENTICATE" | Tx | Rx | Tx | Tx | Rx | Tx | 2749 | 49 | "CANCEL" | | | | Tx | Rx | | 2750 | 69 | "INTERRUPT" | | | | | Tx | Rx | 2751 +-----+----------------+-----+-----+------+------+-------+--------+ 2753 "Tx" ("Rx") means the message is sent (received) by a peer of the 2754 respective role. 2756 13.2. Features 2758 Support for advanced features must be announced by the peers which 2759 implement them. The following is a complete list of advanced 2760 features currently defined or proposed. 2762 +--------+----------------------------------------------------------+ 2763 | Status | Description | 2764 +--------+----------------------------------------------------------+ 2765 | sketch | There is a rough description of an itch to scratch, but | 2766 | | the feature use case isn't clear, and there is no | 2767 | | protocol proposal at all. | 2768 | alpha | The feature use case is still fuzzy and/or the feature | 2769 | | definition is unclear, but there is at least a protocol | 2770 | | level proposal. | 2771 | beta | The feature use case is clearly defined and the feature | 2772 | | definition in the spec is sufficient to write a | 2773 | | prototype implementation. The feature definition and | 2774 | | details may still be incomplete and change. | 2775 | stable | The feature definition in the spec is complete and | 2776 | | stable and the feature use case is field proven in real | 2777 | | applications. There are multiple, interoperatble | 2778 | | implementations. | 2779 +--------+----------------------------------------------------------+ 2781 13.2.1. RPC Features 2782 +----------------------------+--------+---+---+---+----+---+----+ 2783 | Feature | Status | P | B | S | Cr | D | Ce | 2784 +----------------------------+--------+---+---+---+----+---+----+ 2785 | progressive_call_results | beta | | | | X | X | X | 2786 | progressive_calls | sketch | | | | X | X | X | 2787 | call_timeout | alpha | | | | X | X | X | 2788 | call_canceling | alpha | | | | X | X | X | 2789 | caller_identification | alpha | | | | X | X | X | 2790 | call_trustlevels | alpha | | | | | X | X | 2791 | registration_meta_api | beta | | | | | X | | 2792 | pattern_based_registration | beta | | | | | X | X | 2793 | shared_registration | beta | | | | | X | X | 2794 | sharded_registration | alpha | | | | | X | X | 2795 | registration_revocation | alpha | | | | | X | X | 2796 | procedure_reflection | sketch | | | | | X | | 2797 +----------------------------+--------+---+---+---+----+---+----+ 2799 13.2.2. PubSub Features 2801 +-------------------------------+--------+---+---+---+----+---+----+ 2802 | Feature | Status | P | B | S | Cr | D | Ce | 2803 +-------------------------------+--------+---+---+---+----+---+----+ 2804 | subscriber_blackwhite_listing | stable | X | X | | | | | 2805 | publisher_exclusion | stable | X | X | | | | | 2806 | publisher_identification | alpha | X | X | X | | | | 2807 | publication_trustlevels | alpha | | X | X | | | | 2808 | session_meta_api | beta | | X | | | | | 2809 | subscription_meta_api | beta | | X | | | | | 2810 | pattern_based_subscription | beta | | X | X | | | | 2811 | sharded_subscription | alpha | | X | X | | | | 2812 | event_history | alpha | | X | X | | | | 2813 | topic_reflection | sketch | | X | | | | | 2814 +-------------------------------+--------+---+---+---+----+---+----+ 2816 13.2.3. Other Advanced Features 2818 +-----------------------------------+--------+ 2819 | Feature | Status | 2820 +-----------------------------------+--------+ 2821 | challenge-response authentication | beta | 2822 | cookie authentication | beta | 2823 | ticket authentication | beta | 2824 | rawsocket transport | stable | 2825 | batched WS transport | sketch | 2826 | longpoll transport | beta | 2827 | session meta api | beta | 2828 +-----------------------------------+--------+ 2830 13.3. Advanced RPC Features 2832 13.3.1. Progressive Call Results 2834 13.3.1.1. Feature Definition 2836 A procedure implemented by a _Callee_ and registered at a _Dealer_ 2837 may produce progressive results. Progressive results can e.g. be 2838 used to return partial results for long-running operations, or to 2839 chunk the transmission of larger results sets. 2841 The message flow for progressive results involves: 2843 ,------. ,------. ,------. 2844 |Caller| |Dealer| |Callee| 2845 `--+---' `--+---' `--+---' 2846 | CALL | | 2847 | -----------------> | 2848 | | | 2849 | | INVOCATION | 2850 | | ----------------> 2851 | | | 2852 | | YIELD (progress)| 2853 | | <---------------- 2854 | | | 2855 | RESULT (progress)| | 2856 | <----------------- | 2857 | | | 2858 | | YIELD (progress)| 2859 | | <---------------- 2860 | | | 2861 | RESULT (progress)| | 2862 | <----------------- | 2863 | | | 2864 | | | 2865 | ... | ... | 2866 | | | 2867 | | YIELD or ERROR | 2868 | | <---------------- 2869 | | | 2870 | RESULT or ERROR | | 2871 | <----------------- | 2872 ,--+---. ,--+---. ,--+---. 2873 |Caller| |Dealer| |Callee| 2874 `------' `------' `------' 2876 A _Caller_ indicates its willingness to receive progressive results 2877 by setting 2878 CALL.Options.receive_progress|bool := true 2880 _Example._ Caller-to-Dealer "CALL" 2882 [ 2883 48, 2884 77133, 2885 { 2886 "receive_progress": true 2887 }, 2888 "com.myapp.compute_revenue", 2889 [2010, 2011, 2012] 2890 ] 2892 If the _Callee_ supports progressive calls, the _Dealer_ will forward 2893 the _Caller's_ willingness to receive progressive results by setting 2895 INVOCATION.Options.receive_progress|bool := true 2897 _Example._ Dealer-to-Callee "INVOCATION" 2899 [ 2900 68, 2901 87683, 2902 324, 2903 { 2904 "receive_progress": true 2905 }, 2906 [2010, 2011, 2012] 2907 ] 2909 An endpoint implementing the procedure produces progressive results 2910 by sending "YIELD" messages to the _Dealer_ with 2912 YIELD.Options.progress|bool := true 2914 _Example._ Callee-to-Dealer progressive "YIELDs" 2916 [ 2917 70, 2918 87683, 2919 { 2920 "progress": true 2921 }, 2922 ["Y2010", 120] 2923 ] 2925 [ 2926 70, 2927 87683, 2928 { 2929 "progress": true 2930 }, 2931 ["Y2011", 205] 2932 ] 2934 Upon receiving an "YIELD" message from a _Callee_ with 2935 "YIELD.Options.progress == true" (for a call that is still ongoing), 2936 the _Dealer_ will *immediately* send a "RESULT" message to the 2937 original _Caller_ with 2939 RESULT.Details.progress|bool := true 2941 _Example._ Dealer-to-Caller progressive "RESULTs" 2943 [ 2944 50, 2945 77133, 2946 { 2947 "progress": true 2948 }, 2949 ["Y2010", 120] 2950 ] 2952 [ 2953 50, 2954 77133, 2955 { 2956 "progress": true 2957 }, 2958 ["Y2011", 205] 2959 ] 2961 ... 2963 An invocation MUST _always_ end in either a _normal_ "RESULT" or 2964 "ERROR" message being sent by the _Callee_ and received by the 2965 _Dealer_. 2967 _Example._ Callee-to-Dealer final "YIELD" 2969 [ 2970 70, 2971 87683, 2972 {}, 2973 ["Total", 490] 2974 ] 2976 _Example._ Callee-to-Dealer final "ERROR" 2978 [ 2979 4, 2980 87683, 2981 {}, 2982 "com.myapp.invalid_revenue_year", 2983 [1830] 2984 ] 2986 A call MUST _always_ end in either a _normal_ "RESULT" or "ERROR" 2987 message being sent by the _Dealer_ and received by the _Caller_. 2989 _Example._ Dealer-to-Caller final "RESULT" 2991 [ 2992 50, 2993 77133, 2994 {}, 2995 ["Total", 490] 2996 ] 2998 _Example._ Dealer-to-Caller final "ERROR" 3000 [ 3001 4, 3002 77133, 3003 {}, 3004 "com.myapp.invalid_revenue_year", 3005 [1830] 3006 ] 3008 In other words: "YIELD" with "YIELD.Options.progress == true" and 3009 "RESULT" with "RESULT.Details.progress == true" messages may only be 3010 sent _during_ a call or invocation is still ongoing. 3012 The final "YIELD" and final "RESULT" may also be empty, e.g. when all 3013 actual results have already been transmitted in progressive result 3014 messages. 3016 _Example._ Callee-to-Dealer "YIELDs" 3018 [70, 87683, {"progress": true}, ["Y2010", 120]] 3019 [70, 87683, {"progress": true}, ["Y2011", 205]] 3020 ... 3021 [70, 87683, {"progress": true}, ["Total", 490]] 3022 [70, 87683, {}] 3024 _Example._ Dealer-to-Caller "RESULTs" 3026 [50, 77133, {"progress": true}, ["Y2010", 120]] 3027 [50, 77133, {"progress": true}, ["Y2011", 205]] 3028 ... 3029 [50, 77133, {"progress": true}, ["Total", 490]] 3030 [50, 77133, {}] 3032 The progressive "YIELD" and progressive "RESULT" may also be empty, 3033 e.g. when those messages are only used to signal that the procedure 3034 is still running and working, and the actual result is completely 3035 delivered in the final "YIELD" and "RESULT": 3037 _Example._ Callee-to-Dealer "YIELDs" 3039 [70, 87683, {"progress": true}] 3040 [70, 87683, {"progress": true}] 3041 ... 3042 [70, 87683, {}, [["Y2010", 120], ["Y2011", 205], ..., 3043 ["Total", 490]]] 3045 _Example._ Dealer-to-Caller "RESULTs" 3047 [50, 77133, {"progress": true}] 3048 [50, 77133, {"progress": true}] 3049 ... 3050 [50, 77133, {}, [["Y2010", 120], ["Y2011", 205], ..., 3051 ["Total", 490]]] 3053 Note that intermediate, progressive results and/or the final 3054 result MAY have different structure. The WAMP peer implementation 3055 is responsible for mapping everything into a form suitable for 3056 consumption in the host language. 3058 _Example._ Callee-to-Dealer "YIELDs" 3060 [70, 87683, {"progress": true}, ["partial 1", 10]] 3061 [70, 87683, {"progress": true}, [], {"foo": 10, 3062 "bar": "partial 1"}] 3063 ... 3064 [70, 87683, {}, [1, 2, 3], {"moo": "hello"}] 3066 _Example._ Dealer-to-Caller "RESULTs" 3068 [50, 77133, {"progress": true}, ["partial 1", 10]] 3069 [50, 77133, {"progress": true}, [], {"foo": 10, 3070 "bar": "partial 1"}] 3071 ... 3072 [50, 77133, {}, [1, 2, 3], {"moo": "hello"}] 3074 Even if a _Caller_ has indicated it's expectation to receive 3075 progressive results by setting "CALL.Options.receive_progress|bool := 3076 true", a _Callee_ is *not required* to produce progressive results. 3077 "CALL.Options.receive_progress" and 3078 "INVOCATION.Options.receive_progress" are simply indications that the 3079 _Caller_ is prepared to process progressive results, should there be 3080 any produced. In other words, _Callees_ are free to ignore such 3081 "receive_progress" hints at any time. 3083 13.3.1.2. Feature Announcement 3085 Support for this advanced feature MUST be announced by _Callers_ 3086 ("role := "caller""), _Callees_ ("role := "callee"") and _Dealers_ 3087 ("role := "dealer"") via 3089 HELLO.Details.roles..features. 3090 progressive_call_results|bool := true 3092 13.3.2. Progressive Calls 3094 13.3.2.1. Feature Definition 3096 A procedure implemented by a _Callee_ and registered at a _Dealer_ 3097 may receive a progressive call. Progressive results can e.g. be used 3098 to start processing initial data where a larger data set may not yet 3099 have been generated or received by the _Caller_. 3101 See this GitHub issue for more discussion: 3104 13.3.3. Call Timeouts 3106 13.3.3.1. Feature Definition 3108 A _Caller_ might want to issue a call providing a _timeout_ for the 3109 call to finish. 3111 A _timeout_ allows to *automatically* cancel a call after a specified 3112 time either at the _Callee_ or at the _Dealer_. 3114 A _Caller_ specifies a timeout by providing 3116 CALL.Options.timeout|integer 3118 in ms. A timeout value of "0" deactivates automatic call timeout. 3119 This is also the default value. 3121 The timeout option is a companion to, but slightly different from the 3122 "CANCEL" and "INTERRUPT" messages that allow a _Caller_ and _Dealer_ 3123 to *actively* cancel a call or invocation. 3125 In fact, a timeout timer might run at three places: 3127 o _Caller_ 3129 o _Dealer_ 3131 o _Callee_ 3133 13.3.3.2. Feature Announcement 3135 Support for this feature MUST be announced by _Callers_ ("role := 3136 "caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role := 3137 "dealer"") via 3139 HELLO.Details.roles..features.call_timeout|bool := true 3141 13.3.4. Call Canceling 3143 13.3.4.1. Feature Definition 3145 A _Caller_ might want to actively cancel a call that was issued, but 3146 not has yet returned. An example where this is useful could be a 3147 user triggering a long running operation and later changing his mind 3148 or no longer willing to wait. 3150 The message flow between _Callers_, a _Dealer_ and _Callees_ for 3151 canceling remote procedure calls involves the following messages: 3153 o "CANCEL" 3155 o "INTERRUPT" 3157 A call may be cancelled at the _Callee_ 3158 ,------. ,------. ,------. 3159 |Caller| |Dealer| |Callee| 3160 `--+---' `--+---' `--+---' 3161 | CALL | | 3162 | ----------------> | 3163 | | | 3164 | | INVOCATION | 3165 | | ----------------> 3166 | | | 3167 | CANCEL | | 3168 | ----------------> | 3169 | | | 3170 | | INTERRUPT | 3171 | | ----------------> 3172 | | | 3173 | | ERROR | 3174 | | <---------------- 3175 | | | 3176 | ERROR | | 3177 | <---------------- | 3178 ,--+---. ,--+---. ,--+---. 3179 |Caller| |Dealer| |Callee| 3180 `------' `------' `------' 3182 A call may be cancelled at the _Dealer_ 3183 ,------. ,------. ,------. 3184 |Caller| |Dealer| |Callee| 3185 `--+---' `--+---' `--+---' 3186 | CALL | | 3187 | ----------------> | 3188 | | | 3189 | | INVOCATION | 3190 | | ----------------> 3191 | | | 3192 | CANCEL | | 3193 | ----------------> | 3194 | | | 3195 | ERROR | | 3196 | <---------------- | 3197 | | | 3198 | | INTERRUPT | 3199 | | ----------------> 3200 | | | 3201 | | ERROR | 3202 | | <---------------- 3203 ,--+---. ,--+---. ,--+---. 3204 |Caller| |Dealer| |Callee| 3205 `------' `------' `------' 3207 A _Caller_ cancels a remote procedure call initiated (but not yet 3208 finished) by sending a "CANCEL" message to the _Dealer_: 3210 [CANCEL, CALL.Request|id, Options|dict] 3212 A _Dealer_ cancels an invocation of an endpoint initiated (but not 3213 yet finished) by sending a "INTERRUPT" message to the _Callee_: 3215 [INTERRUPT, INVOCATION.Request|id, Options|dict] 3217 Options: 3219 CANCEL.Options.mode|string == "skip" | "kill" | "killnowait" 3221 13.3.4.2. Feature Announcement 3223 Support for this feature MUST be announced by _Callers_ ("role := 3224 "caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role := 3225 "dealer"") via 3227 HELLO.Details.roles..features.call_canceling|bool := true 3229 13.3.5. Caller Identification 3231 13.3.5.1. Feature Definition 3233 A _Caller_ MAY *request* the disclosure of its identity (its WAMP 3234 session ID) to endpoints of a routed call via 3236 CALL.Options.disclose_me|bool := true 3238 _Example_ 3240 [48, 7814135, {"disclose_me": true}, "com.myapp.echo", 3241 ["Hello, world!"]] 3243 If above call is issued by a _Caller_ with WAMP session ID "3335656", 3244 the _Dealer_ sends an "INVOCATION" message to _Callee_ with the 3245 _Caller's_ WAMP session ID in "INVOCATION.Details.caller": 3247 _Example_ 3249 [68, 6131533, 9823526, {"caller": 3335656}, ["Hello, world!"]] 3251 Note that a _Dealer_ MAY disclose the identity of a _Caller_ even 3252 without the _Caller_ having explicitly requested to do so when the 3253 _Dealer_ configuration (for the called procedure) is setup to do so. 3255 A _Dealer_ MAY deny a _Caller's_ request to disclose its identity: 3257 _Example_ 3259 [8, 7814135, "wamp.error.disclose_me.not_allowed"] 3261 A _Callee_ MAY *request* the disclosure of caller identity via 3263 REGISTER.Options.disclose_caller|bool := true 3265 _Example_ 3267 [64, 927639114088448, {"disclose_caller":true}, 3268 "com.maypp.add2"] 3270 With the above registration, the registered procedure is called with 3271 the caller's sessionID as part of the call details object. 3273 13.3.5.2. Feature Announcement 3275 Support for this feature MUST be announced by _Callers_ ("role := 3276 "caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role := 3277 "dealer"") via 3279 HELLO.Details.roles..features. 3280 caller_identification|bool := true 3282 13.3.6. Call Trust Levels 3284 13.3.6.1. Feature Defintion 3286 A _Dealer_ may be configured to automatically assign _trust levels_ 3287 to calls issued by _Callers_ according to the _Dealer_ configuration 3288 on a per-procedure basis and/or depending on the application defined 3289 role of the (authenticated) _Caller_. 3291 A _Dealer_ supporting trust level will provide 3293 INVOCATION.Details.trustlevel|integer 3295 in an "INVOCATION" message sent to a _Callee_. The trustlevel "0" 3296 means lowest trust, and higher integers represent (application- 3297 defined) higher levels of trust. 3299 _Example_ 3301 [68, 6131533, 9823526, {"trustlevel": 2}, ["Hello, world!"]] 3303 In above event, the _Dealer_ has (by configuration and/or other 3304 information) deemed the call (and hence the invocation) to be of 3305 trustlevel "2". 3307 13.3.6.2. Feature Announcement 3309 Support for this feature MUST be announced by _Callees_ ("role := 3310 "callee"") and _Dealers_ ("role := "dealer"") via 3312 HELLO.Details.roles..features.call_trustlevels|bool := true 3314 13.3.7. Registration Meta API 3316 13.3.7.1. Feature Definition 3317 13.3.7.1.1. Introduction 3319 *Registration Meta Events* are fired when registrations are first 3320 created, when _Callees_ are attached (removed) to (from) a 3321 registration, and when registrations are finally destroyed. 3323 Furthermore, WAMP allows actively retrieving information about 3324 registrations via *Registration Meta Procedures*. 3326 Meta-events are created by the router itself. This means that the 3327 events as well as the data received when calling a meta-procedure can 3328 be accorded the same trust level as the router. 3330 Note that an implementation that only supports a _Broker_ or 3331 _Dealer_ role, not both at the same time, essentially cannot offer 3332 the *Registration Meta API*, as it requires both roles to support 3333 this feature. 3335 13.3.7.1.2. Registration Meta Events 3337 A client can subscribe to the following registration meta-events, 3338 which cover the lifecycle of a registration: 3340 o "wamp.registration.on_create": Fired when a registration is 3341 created through a registration request for an URI which was 3342 previously without a registration. 3344 o "wamp.registration.on_register": Fired when a _Callee_ session is 3345 added to a registration. 3347 o "wamp.registration.on_unregister": Fired when a _Callee_ session 3348 is removed from a registration. 3350 o "wamp.registration.on_delete": Fired when a registration is 3351 deleted after the last _Callee_ session attached to it has been 3352 removed. 3354 A "wamp.registration.on_register" event MUST be fired subsequent to a 3355 "wamp.registration.on_create" event, since the first registration 3356 results in both the creation of the registration and the addition of 3357 a session. 3359 Similarly, the "wamp.registration.on_delete" event MUST be preceded 3360 by a "wamp.registration.on_unregister" event. 3362 *Registration Meta Events* MUST be dispatched by the router to the 3363 same realm as the WAMP session which triggered the event. 3365 13.3.7.1.2.1. wamp.registration.on_create 3367 Fired when a registration is created through a registration request 3368 for an URI which was previously without a registration. 3370 *Event Arguments* 3372 o "session|id": The session ID performing the registration request. 3374 o "RegistrationDetails|dict": Information on the created 3375 registration. 3377 *Object Schemas* 3379 RegistrationDetails := 3380 { 3381 "id": registration|id, 3382 "created": time_created|iso_8601_string, 3383 "uri": procedure|uri, 3384 "match": match_policy|string, 3385 "invoke": invocation_policy|string 3386 } 3388 See Pattern-based Registrations [2] for a description of 3389 "match_policy". 3391 NOTE: invocation_policy IS NOT YET DESCRIBED IN THE ADVANCED SPEC 3393 13.3.7.1.2.2. wamp.registration.on_register 3395 Fired when a session is added to a registration. 3397 *Event Arguments* 3399 o "session|id": The ID of the session being added to a registration. 3401 o "registration|id": The ID of the registration to which a session 3402 is being added. 3404 13.3.7.1.2.3. wamp.registration.on_unregister 3406 Fired when a session is removed from a subscription. 3408 *Event Arguments* 3410 o "session|id": The ID of the session being removed from a 3411 registration. 3413 o "registration|id": The ID of the registration from which a session 3414 is being removed. 3416 13.3.7.1.2.4. wamp.registration.on_delete 3418 Fired when a registration is deleted after the last session attached 3419 to it has been removed. 3421 *Event Arguments* 3423 o "session|id": The ID of the last session being removed from a 3424 registration. 3426 o "registration|id": The ID of the registration being deleted. 3428 13.3.7.1.3. Registration Meta-Procedures 3430 A client can actively retrieve information about registrations via 3431 the following meta-procedures: 3433 o "wamp.registration.list": Retrieves registration IDs listed 3434 according to match policies. 3436 o "wamp.registration.lookup": Obtains the registration (if any) 3437 managing a procedure, according to some match policy. 3439 o "wamp.registration.match": Obtains the registration best matching 3440 a given procedure URI. 3442 o "wamp.registration.get": Retrieves information on a particular 3443 registration. 3445 o "wamp.registration.list_callees": Retrieves a list of session IDs 3446 for sessions currently attached to the registration. 3448 o "wamp.registration.count_callees": Obtains the number of sessions 3449 currently attached to the registration. 3451 13.3.7.1.3.1. wamp.registration.list 3453 Retrieves registration IDs listed according to match policies. 3455 *Arguments* 3457 o None 3459 *Results* 3460 o "RegistrationLists|dict": A dictionary with a list of registration 3461 IDs for each match policy. 3463 *Object Schemas* 3465 RegistrationLists := 3466 { 3467 "exact": registration_ids|list, 3468 "prefix": registration_ids|list, 3469 "wildcard": registration_ids|list 3470 } 3472 See Pattern-based Registrations [3] for a description of match 3473 policies. 3475 13.3.7.1.3.2. wamp.registration.lookup 3477 Obtains the registration (if any) managing a procedure, according to 3478 some match policy. 3480 *Arguments* 3482 o "procedure|uri": The procedure to lookup the registration for. 3484 o (Optional) "options|dict": Same options as when registering a 3485 procedure. 3487 *Results* 3489 o (Nullable) "registration|id": The ID of the registration managing 3490 the procedure, if found, or null. 3492 13.3.7.1.3.3. wamp.registration.match 3494 Obtains the registration best matching a given procedure URI. 3496 *Arguments* 3498 o "procedure|uri": The procedure URI to match 3500 *Results* 3502 o (Nullable) "registration|id": The ID of best matching 3503 registration, or null. 3505 13.3.7.1.3.4. wamp.registration.get 3507 Retrieves information on a particular registration. 3509 *Arguments* 3511 o "registration|id": The ID of the registration to retrieve. 3513 *Results* 3515 o "RegistrationDetails|dict": Details on the registration. 3517 *Error URIs* 3519 o "wamp.error.no_such_registration": No registration with the given 3520 ID exists on the router. 3522 *Object Schemas* 3524 RegistrationDetails := 3525 { 3526 "id": registration|id, 3527 "created": time_created|iso_8601_string, 3528 "uri": procedure|uri, 3529 "match": match_policy|string, 3530 "invoke": invocation_policy|string 3531 } 3533 See Pattern-based Registrations [4] for a description of match 3534 policies. 3536 _NOTE: invocation_policy IS NOT YET DESCRIBED IN THE ADVANCED SPEC_ 3538 13.3.7.1.3.5. wamp.registration.list_callees 3540 Retrieves a list of session IDs for sessions currently attached to 3541 the registration. 3543 *Arguments* 3545 o "registration|id": The ID of the registration to get calles for. 3547 *Results* 3549 o "callee_ids|list": A list of WAMP session IDs of callees currently 3550 attached to the registration. 3552 *Error URIs* 3553 o "wamp.error.no_such_registration": No registration with the given 3554 ID exists on the router. 3556 13.3.7.1.3.6. wamp.registration.count_callees 3558 Obtains the number of sessions currently attached to a registration. 3560 *Arguments* 3562 o "registration|id": The ID of the registration to get the number of 3563 callees for. 3565 *Results* 3567 o "count|int": The number of callees currently attached to a 3568 registration. 3570 *Error URIs* 3572 o "wamp.error.no_such_registration": No registration with the given 3573 ID exists on the router. 3575 13.3.7.2. Feature Announcement 3577 Support for this feature MUST be announced by a _Dealers_ ("role := 3578 "dealer"") via: 3580 HELLO.Details.roles..features. 3581 session_meta_api|bool := true 3583 *Example* 3585 Here is a "WELCOME" message from a _Router_ with support for both the 3586 _Broker_ and _Dealer_ role, and with support for *Registration Meta 3587 API*: 3589 [ 3590 2, 3591 4580268554656113, 3592 { 3593 "authid":"OL3AeppwDLXiAAPbqm9IVhnw", 3594 "authrole": "anonymous", 3595 "authmethod": "anonymous", 3596 "roles": { 3597 "broker": { 3598 "features": { 3599 } 3600 }, 3601 "dealer": { 3602 "features": { 3603 "registration_meta_api": true 3604 } 3605 } 3606 } 3607 } 3608 ] 3610 13.3.8. Pattern-based Registrations 3612 13.3.8.1. Feature Definition 3614 13.3.8.1.1. Introduction 3616 By default, _Callees_ register procedures with *exact matching 3617 policy*. That is a call will only be routed to a _Callee_ by the 3618 _Dealer_ if the procedure called ("CALL.Procedure") _exactly_ matches 3619 the endpoint registered ("REGISTER.Procedure"). 3621 A _Callee_ might want to register procedures based on a _pattern_. 3622 This can be useful to reduce the number of individual registrations 3623 to be set up or to subscribe to a open set of topics, not known 3624 beforehand by the _Subscriber_. 3626 If the _Dealer_ and the _Callee_ support *pattern-based 3627 registrations*, this matching can happen by 3629 o *prefix-matching policy* 3631 o *wildcard-matching policy* 3633 13.3.8.1.2. Prefix Matching 3635 A _Callee_ requests *prefix-matching policy* with a registration 3636 request by setting 3638 REGISTER.Options.match|string := "prefix" 3640 _Example_ 3642 [ 3643 64, 3644 612352435, 3645 { 3646 "match": "prefix" 3647 }, 3648 "com.myapp.myobject1" 3649 ] 3651 When a *prefix-matching policy* is in place, any call with a 3652 procedure that has "REGISTER.Procedure" as a _prefix_ will match the 3653 registration, and potentially be routed to _Callees_ on that 3654 registration. 3656 In above example, the following calls with "CALL.Procedure" 3658 o "com.myapp.myobject1.myprocedure1" 3660 o "com.myapp.myobject1-mysubobject1" 3662 o "com.myapp.myobject1.mysubobject1.myprocedure1" 3664 o "com.myapp.myobject1" 3666 will all apply for call routing. A call with one of the following 3667 "CALL.Procedure" 3669 o "com.myapp.myobject2" 3671 o "com.myapp.myobject" 3673 will not apply. 3675 13.3.8.1.3. Wildcard Matching 3677 A _Callee_ requests *wildcard-matching policy* with a registration 3678 request by setting 3680 REGISTER.Options.match|string := "wildcard" 3682 Wildcard-matching allows to provide wildcards for *whole* URI 3683 components. 3685 _Example_ 3687 [ 3688 64, 3689 612352435, 3690 { 3691 "match": "wildcard" 3692 }, 3693 "com.myapp..myprocedure1" 3694 ] 3696 In the above registration request, the 3rd URI component is empty, 3697 which signals a wildcard in that URI component position. In this 3698 example, calls with "CALL.Procedure" e.g. 3700 o "com.myapp.myobject1.myprocedure1" 3702 o "com.myapp.myobject2.myprocedure1" 3704 will all apply for call routing. Calls with "CALL.Procedure" e.g. 3706 o "com.myapp.myobject1.myprocedure1.mysubprocedure1" 3708 o "com.myapp.myobject1.myprocedure2" 3710 o "com.myapp2.myobject1.myprocedure1" 3712 will not apply for call routing. 3714 When a single call matches more than one of a _Callees_ 3715 registrations, the call MAY be routed for invocation on multiple 3716 registrations, depending on call settings. 3718 13.3.8.1.4. General 3720 13.3.8.1.4.1. No set semantics 3722 Since each _Callee_'s' registrations "stands on it's own", there is 3723 no _set semantics_ implied by pattern-based registrations. 3725 E.g. a _Callee_ cannot register to a broad pattern, and then 3726 unregister from a subset of that broad pattern to form a more complex 3727 registration. Each registration is separate. 3729 13.3.8.1.4.2. Calls matching multiple registrations 3731 The behavior when a single call matches more than one of a _Callee's_ 3732 registrations or more than one registration in general is still being 3733 discussed - see . 3735 13.3.8.1.4.3. Concrete procedure called 3737 If an endpoint was registered with a pattern-based matching policy, a 3738 _Dealer_ MUST supply the original "CALL.Procedure" as provided by the 3739 _Caller_ in 3741 INVOCATION.Details.procedure 3743 to the _Callee_. 3745 _Example_ 3747 [ 3748 68, 3749 6131533, 3750 9823527, 3751 { 3752 "procedure": "com.myapp.procedure.proc1" 3753 }, 3754 ["Hello, world!"] 3755 ] 3757 13.3.8.2. Feature Announcement 3759 Support for this feature MUST be announced by _Callees_ ("role := 3760 "callee"") and _Dealers_ ("role := "dealer"") via 3762 HELLO.Details.roles..features. 3763 pattern_based_registration|bool := true 3765 13.3.9. Shared Registration 3767 Feature status: *alpha* 3769 13.3.9.1. Feature Definition 3771 As a default, only a single *Callee* may register a procedure for an 3772 URI. 3774 There are use cases where more flexibility is required. As an 3775 example, for an application component with a high computing load, 3776 several instances may run, and load balancing of calls across these 3777 may be desired. As another example, in an an application a second or 3778 third component providing a procedure may run, which are only to be 3779 called in case the primary component is no longer reachable (hot 3780 standby). 3782 When shared registrations are supported, then the first *Callee* to 3783 register a procedure for a particular URI MAY determine that 3784 additional registrations for this URI are allowed, and what 3785 *Invocation Rules* to apply in case such additional registrations are 3786 made. 3788 This is done through setting 3790 REGISTER.Options.invoke|string := 3792 where is one of 3794 o 'single' 3796 o 'roundrobin' 3798 o 'random' 3800 o 'first' 3802 o 'last' 3804 If the option is not set, 'single' is applied as a default. 3806 With 'single', the *Dealer* MUST fail all subsequent attempts to 3807 register a procedure for the URI while the registration remains in 3808 existence. 3810 With the other values, the *Dealer* MUST fail all subsequent attempst 3811 to register a procedure for the URI where the value for this option 3812 does not match that of the initial registration. 3814 13.3.9.1.1. Load Balancing 3816 For sets of registrations registered using either 'roundrobin' or 3817 'random', load balancing is performed across calls to the URI. 3819 For 'roundrobin', callees are picked subsequently from the list of 3820 registrations (ordered by the order of registration), with the 3821 picking looping back to the beginning of the list once the end has 3822 been reached. 3824 For 'random' a callee is picked randomly from the list of 3825 registrations for each call. 3827 13.3.9.1.2. Hot Stand-By 3829 For sets of registrations registered using either 'first' or 'last', 3830 the first respectively last callee on the current list of 3831 registrations (ordered by the order of registration) is called. 3833 13.3.9.2. Feature Announcement 3835 Support for this feature MUST be announced by _Callees_ ("role := 3836 "callee"") and _Dealers_ ("role := "dealer"") via 3838 HELLO.Details.roles..features. 3839 shared_registration|bool := true 3841 13.3.10. Sharded Registration 3843 Feature status: *sketch* 3845 13.3.10.1. Feature Definition 3847 *Sharded Registrations* are intended to allow calling a procedure 3848 which is offered by a sharded database, by routing the call to a 3849 single shard. 3851 13.3.10.2. "Partitioned" Calls 3853 If "CALL.Options.runmode == "partition"", then "CALL.Options.rkey" 3854 MUST be present. 3856 The call is then routed to all endpoints that were registered .. 3858 The call is then processed as for "All" Calls. 3860 13.3.10.3. Feature Announcement 3862 Support for this feature MUST be announced by _Callers_ ("role := 3863 "caller""), _Callees_ ("role := "callee"") and _Dealers_ ("role := 3864 "dealer"") via 3866 HELLO.Details.roles..features.sharded_registration|bool := true 3868 13.3.11. Registration Revocation 3870 13.3.11.1. Feature Definition 3872 Actively and forcefully revoke a previously granted registration from 3873 a session. 3875 13.3.11.2. Feature Announcement 3877 13.3.12. Procedure Reflection 3879 Feature status: *sketch* 3881 _Reflection_ denotes the ability of WAMP peers to examine the 3882 procedures, topics and errors provided or used by other peers. 3884 I.e. a WAMP _Caller_, _Callee_, _Subscriber_ or _Publisher_ may be 3885 interested in retrieving a machine readable list and description of 3886 WAMP procedures and topics it is authorized to access or provide in 3887 the context of a WAMP session with a _Dealer_ or _Broker_. 3889 Reflection may be useful in the following cases: 3891 o documentation 3893 o discoverability 3895 o generating stubs and proxies 3897 WAMP predefines the following procedures for performing run-time 3898 reflection on WAMP peers which act as _Brokers_ and/or _Dealers_. 3900 Predefined WAMP reflection procedures to _list_ resources by type: 3902 wamp.reflection.topic.list 3903 wamp.reflection.procedure.list 3904 wamp.reflection.error.list 3906 Predefined WAMP reflection procedures to _describe_ resources by 3907 type: 3909 wamp.reflection.topic.describe 3910 wamp.reflection.procedure.describe 3911 wamp.reflection.error.describe 3913 A peer that acts as a _Broker_ SHOULD announce support for the 3914 reflection API by sending 3915 HELLO.Details.roles.broker.reflection|bool := true 3917 A peer that acts as a _Dealer_ SHOULD announce support for the 3918 reflection API by sending 3920 HELLO.Details.roles.dealer.reflection|bool := true 3922 Since _Brokers_ might provide (broker) procedures and _Dealers_ 3923 might provide (dealer) topics, both SHOULD implement the complete 3924 API above (even if the peer only implements one of _Broker_ or 3925 _Dealer_ roles). 3927 *Reflection* 3929 A topic or procedure is defined for reflection: 3931 wamp.reflect.define 3933 A topic or procedure was asked to be described (reflected upon): 3935 wamp.reflect.describe 3937 *Reflection* 3939 A topic or procedure has been defined for reflection: 3941 wamp.reflect.on_define 3943 A topic or procedure has been unfined from reflection: 3945 wamp.reflect.on_undefine 3947 13.4. Advanced PubSub Features 3949 13.4.1. Subscriber Black- and Whitelisting 3951 13.4.1.1. Introduction 3953 *Subscriber Black- and Whitelisting* is an advanced _Broker_ feature 3954 where a _Publisher_ is able to restrict the set of receivers of a 3955 published event. 3957 Under normal Publish & Subscriber event dispatching, a _Broker_ will 3958 dispatch a published event to all (authorized) _Subscribers_ other 3959 than the _Publisher_ itself. This set of receivers can be further 3960 reduced on a per-publication basis by the _Publisher_ using 3961 *Subscriber Black- and Whitelisting*. 3963 The _Publisher_ can explicitly *exclude* _Subscribers_ based on WAMP 3964 "sessionid", "authid" or "authrole". This is referred to as 3965 *Blacklisting*. 3967 A _Publisher_ may also explicitly define a *eligible* list of 3968 *Subscribers** based on WAMP "sessionid", "authid" or "authrole". 3969 This is referred to as *Whitelisting*. 3971 13.4.1.2. Use Cases 3973 13.4.1.2.1. Avoiding Callers from being self-notified 3975 Consider an application that exposes a procedure to update a product 3976 price. The procedure might not only actually update the product 3977 price (e.g. in a backend database), but additionally publish an event 3978 with the updated product price, so that *all* application components 3979 get notified actively of the new price. 3981 However, the application might want to exclude the originator of the 3982 product price update (the *Caller* of the price update procedure) 3983 from receiving the update event - as the originator naturally already 3984 knows the new price, and might get confused when it receives an 3985 update the *Caller* has triggered himself. 3987 The product price update procedure can use 3988 "PUBLISH.Options.exclude|list[int]" to exclude the *Caller* of the 3989 procedure. 3991 Note that the product price update procedure needs to know the 3992 session ID of the *Caller* to be able to exclude him. For this, 3993 please see *Caller Identification*. 3995 A similar approach can be used for other CRUD-like procedures. 3997 13.4.1.2.2. Restricting receivers of sensitive information 3999 Consider an application with users that have different "authroles", 4000 such as "manager" and "staff" that publishes events with updates to 4001 "customers". The topics being published to could be structured like 4003 com.example.myapp.customer. 4005 The application might want to restrict the receivers of customer 4006 updates depending on the "authrole" of the user. E.g. a user 4007 authenticated under "authrole" "manager" might be allowed to receive 4008 any kind of customer update, including personal and business 4009 sensitive information. A user under "authrole" "staff" might only be 4010 allowed to receive a subset of events. 4012 The application can publish *all* customer updates to the *same* 4013 topic "com.example.myapp.customer." and use 4014 "PUBLISH.Options.eligible_authrole|list[string]" to safely restrict 4015 the set of actual receivers as desired. 4017 13.4.1.3. Feature Definition 4019 A _Publisher_ may restrict the actual receivers of an event from the 4020 set of _Subscribers_ through the use of 4022 o Blacklisting Options 4024 * "PUBLISH.Options.exclude|list[int]" 4026 * "PUBLISH.Options.exclude_authid|list[string]" 4028 * "PUBLISH.Options.exclude_authrole|list[string]" 4030 o Whitelisting Options 4032 * "PUBLISH.Options.eligible|list[int]" 4034 * "PUBLISH.Options.eligible_authid|list[string]" 4036 * "PUBLISH.Options.eligible_authrole|list[string]" 4038 "PUBLISH.Options.exclude" is a list of integers with WAMP 4039 "sessionids" providing an explicit list of (potential) _Subscribers_ 4040 that won't receive a published event, even though they may be 4041 subscribed. In other words, "PUBLISH.Options.exclude" is a 4042 *blacklist* of (potential) _Subscribers_. 4044 "PUBLISH.Options.eligible" is a list of integeres with WAMP WAMP 4045 "sessionids" providing an explicit list of (potential) _Subscribers_ 4046 that are allowed to receive a published event. In other words, 4047 "PUBLISH.Options.eligible" is a *whitelist* of (potential) 4048 _Subscribers_. 4050 The "exclude_authid", "exclude_authrole", "eligible_authid" and 4051 "eligible_authrole" options work similar, but not on the basis of 4052 WAMP "sessionid", but "authid" and "authrole". 4054 An (authorized) _Subscriber_ to topic T will receive an event 4055 published to T if and only if all of the following statements hold 4056 true: 4058 1. if there is an "eligible" attribute present, the _Subscriber_'s 4059 "sessionid" is in this list 4061 2. if there is an "eligible_authid" attribute present, the 4062 _Subscriber_'s "authid" is in this list 4064 3. if there is an "eligible_authrole" attribute present, the 4065 _Subscriber_'s "authrole" is in this list 4067 4. if there is an "exclude attribute" present, the _Subscriber_'s 4068 "sessionid" is NOT in this list 4070 5. if there is an "exclude_authid" attribute present, the 4071 _Subscriber_'s "authid" is NOT in this list 4073 6. if there is an "exclude_authrole" attribute present, the 4074 _Subscriber_'s "authrole" is NOT in this list 4076 For example, if both "PUBLISH.Options.exclude" and 4077 "PUBLISH.Options.eligible" are present, the _Broker_ will dispatch 4078 events published only to _Subscribers_ that are not explicitly 4079 excluded in "PUBLISH.Options.exclude" *and* which are explicitly 4080 eligible via "PUBLISH.Options.eligible". 4082 _Example_ 4084 [ 4085 16, 4086 239714735, 4087 { 4088 "exclude": [ 4089 7891255, 4090 1245751 4091 ] 4092 }, 4093 "com.myapp.mytopic1", 4094 [ 4095 "Hello, world!" 4096 ] 4097 ] 4099 The above event will get dispatched to all _Subscribers_ of 4100 "com.myapp.mytopic1", but not WAMP sessions with IDs "7891255" or 4101 "1245751" (and also not the publishing session). 4103 _Example_ 4105 [ 4106 16, 4107 239714735, 4108 { 4109 "eligible": [ 4110 7891255, 4111 1245751 4112 ] 4113 }, 4114 "com.myapp.mytopic1", 4115 [ 4116 "Hello, world!" 4117 ] 4118 ] 4120 The above event will get dispatched to WAMP sessions with IDs 4121 "7891255" or "1245751" only - but only if those are actually 4122 subscribed to the topic "com.myapp.mytopic1". 4124 _Example_ 4126 [ 4127 16, 4128 239714735, 4129 { 4130 "eligible": [ 4131 7891255, 4132 1245751, 4133 9912315 4134 ], 4135 "exclude": [ 4136 7891255 4137 ] 4138 }, 4139 "com.myapp.mytopic1", 4140 [ 4141 "Hello, world!" 4142 ] 4143 ] 4145 The above event will get dispatched to WAMP sessions with IDs 4146 "1245751" or "9912315" only, since "7891255" is excluded - but only 4147 if those are actually subscribed to the topic "com.myapp.mytopic1". 4149 13.4.1.4. Feature Announcement 4151 Support for this feature MUST be announced by _Publishers_ ("role := 4152 "publisher"") and _Brokers_ ("role := "broker"") via 4154 HELLO.Details.roles..features. 4155 subscriber_blackwhite_listing|bool := true 4157 13.4.2. Publisher Exclusion 4159 13.5. Feature Definition 4161 By default, a _Publisher_ of an event will *not* itself receive an 4162 event published, even when subscribed to the "Topic" the _Publisher_ 4163 is publishing to. This behavior can be overridden using this 4164 feature. 4166 To override the exclusion of a publisher from it's own publication, 4167 the "PUBLISH" message must include the following option: 4169 PUBLISH.Options.exclude_me|bool 4171 When publishing with "PUBLISH.Options.exclude_me := false", the 4172 _Publisher_ of the event will receive that event, if it is subscribed 4173 to the "Topic" published to. 4175 _Example_ 4177 [ 4178 16, 4179 239714735, 4180 { 4181 "exclude_me": false 4182 }, 4183 "com.myapp.mytopic1", 4184 ["Hello, world!"] 4185 ] 4187 In this example, the _Publisher_ will receive the published event, if 4188 it is subscribed to "com.myapp.mytopic1". 4190 13.6. Feature Announcement 4192 Support for this feature MUST be announced by _Publishers_ ("role := 4193 "publisher"") and _Brokers_ ("role := "broker"") via 4195 HELLO.Details.roles..features. 4196 publisher_exclusion|bool := true 4198 13.6.1. Publisher Identification 4200 13.6.1.1. Feature Definition 4202 A _Publisher_ may request the disclosure of its identity (its WAMP 4203 session ID) to receivers of a published event by setting 4205 PUBLISH.Options.disclose_me|bool := true 4207 _Example_ 4209 [16, 239714735, {"disclose_me": true}, "com.myapp.mytopic1", 4210 ["Hello, world!"]] 4212 If above event is published by a _Publisher_ with WAMP session ID 4213 "3335656", the _Broker_ would send an "EVENT" message to 4214 _Subscribers_ with the _Publisher's_ WAMP session ID in 4215 "EVENT.Details.publisher": 4217 _Example_ 4219 [36, 5512315355, 4429313566, {"publisher": 3335656}, 4220 ["Hello, world!"]] 4222 Note that a _Broker_ may deny a _Publisher's_ request to disclose its 4223 identity: 4225 _Example_ 4227 [8, 239714735, {}, "wamp.error.option_disallowed.disclose_me"] 4229 A _Broker_ may also (automatically) disclose the identity of a 4230 _Publisher_ even without the _Publisher_ having explicitly requested 4231 to do so when the _Broker_ configuration (for the publication topic) 4232 is set up to do so. 4234 13.6.1.2. Feature Announcement 4236 Support for this feature MUST be announced by _Publishers_ ("role := 4237 "publisher""), _Brokers_ ("role := "broker"") and _Subscribers_ 4238 ("role := "subscriber"") via 4240 HELLO.Details.roles..features. 4241 publisher_identification|bool := true 4243 13.6.2. Publication Trust Levels 4245 13.6.2.1. Feature Definition 4247 A _Broker_ may be configured to automatically assign _trust levels_ 4248 to events published by _Publishers_ according to the _Broker_ 4249 configuration on a per-topic basis and/or depending on the 4250 application defined role of the (authenticated) _Publisher_. 4252 A _Broker_ supporting trust level will provide 4254 EVENT.Details.trustlevel|integer 4256 in an "EVENT" message sent to a _Subscriber_. The trustlevel "0" 4257 means lowest trust, and higher integers represent (application- 4258 defined) higher levels of trust. 4260 _Example_ 4262 [36, 5512315355, 4429313566, {"trustlevel": 2}, 4263 ["Hello, world!"]] 4265 In above event, the _Broker_ has (by configuration and/or other 4266 information) deemed the event publication to be of trustlevel "2". 4268 13.6.2.2. Feature Announcement 4270 Support for this feature MUST be announced by _Subscribers_ ("role := 4271 "subscriber"") and _Brokers_ ("role := "broker"") via 4273 HELLO.Details.roles..features. 4274 publication_trustlevels|bool := true 4276 13.6.3. Subscription Meta API 4278 Within an application, it may be desirable for a publisher to know 4279 whether a publication to a specific topic currently makes sense, i.e. 4280 whether there are any subscribers who would receive an event based on 4281 the publication. It may also be desirable to keep a current count of 4282 subscribers to a topic to then be able to filter out any subscribers 4283 who are not supposed to receive an event. 4285 Subscription _meta-events_ are fired when topics are first created, 4286 when clients subscribe/unsubscribe to them, and when topics are 4287 deleted. WAMP allows retrieving information about subscriptions via 4288 subscription _meta-procedures_. 4290 Support for this feature MUST be announced by Brokers via 4291 HELLO.Details.roles.broker.features.subscription_meta_api| 4292 bool := true 4294 Meta-events are created by the router itself. This means that the 4295 events as well as the data received when calling a meta-procedure can 4296 be accorded the same trust level as the router. 4298 13.6.3.1. Subscription Meta-Events 4300 A client can subscribe to the following session meta-events, which 4301 cover the lifecycle of a subscription: 4303 o "wamp.subscription.on_create": Fired when a subscription is 4304 created through a subscription request for a topic which was 4305 previously without subscribers. 4307 o "wamp.subscription.on_subscribe": Fired when a session is added to 4308 a subscription. 4310 o "wamp.subscription.on_unsubscribe": Fired when a session is 4311 removed from a subscription. 4313 o "wamp.subscription.on_delete": Fired when a subscription is 4314 deleted after the last session attached to it has been removed. 4316 A "wamp.subscription.on_subscribe" event MUST always be fired 4317 subsequent to a "wamp.subscription.on_create" event, since the first 4318 subscribe results in both the creation of the subscription and the 4319 addition of a session. Similarly, the "wamp.subscription.on_delete" 4320 event MUST always be preceded by a "wamp.subscription.on_unsubscribe" 4321 event. 4323 The WAMP subscription meta events shall be dispatched by the router 4324 to the same realm as the WAMP session which triggered the event. 4326 13.6.3.1.1. Meta-Event Specifications 4328 13.6.3.1.1.1. wamp.subscription.on_create 4330 Fired when a subscription is created through a subscription request 4331 for a topic which was previously without subscribers. 4333 *Event Arguments* 4335 o "session|id": ID of the session performing the subscription 4336 request. 4338 o "SubscriptionDetails|dict": Information on the created 4339 subscription. 4341 *Object Schemas* 4343 SubscriptionDetails := 4344 { 4345 "id": subscription|id, 4346 "created": time_created|iso_8601_string, 4347 "uri": topic|uri, 4348 "match": match_policy|string 4349 } 4351 See Section 13.6.4 for a description of "match_policy". 4353 13.6.3.1.1.2. wamp.subscription.on_subscribe 4355 Fired when a session is added to a subscription. 4357 *Event Arguments* 4359 o "session|id": ID of the session being added to a subscription. 4361 o "subscription|id": ID of the subscription to which the session is 4362 being added. 4364 13.6.3.1.1.3. wamp.subscription.on_unsubscribe 4366 Fired when a session is removed from a subscription. 4368 *Event Arguments* 4370 o "session|id": ID of the session being removed from a subscription. 4372 o "subscription|id": ID of the subscription from which the session 4373 is being removed. 4375 13.6.3.1.1.4. wamp.subscription.on_delete 4377 Fired when a subscription is deleted after the last session attached 4378 to it has been removed. 4380 *Arguments* 4382 o "session|id": ID of the last session being removed from a 4383 subscription. 4385 o "subscription|id": ID of the subscription being deleted. 4387 13.6.3.2. Subscription Meta-Procedures 4389 A client can actively retrieve information about subscriptions via 4390 the following meta-procedures: 4392 o "wamp.subscription.list": Retrieves subscription IDs listed 4393 according to match policies. 4395 o "wamp.subscription.lookup": Obtains the subscription (if any) 4396 managing a topic, according to some match policy. 4398 o "wamp.subscription.match": Retrieves a list of IDs of 4399 subscriptions matching a topic URI, irrespective of match policy. 4401 o "wamp.subscription.get": Retrieves information on a particular 4402 subscription. 4404 o "wamp.subscription.list_subscribers": Retrieves a list of session 4405 IDs for sessions currently attached to the subscription. 4407 o "wamp.subscription.count_subscribers": Obtains the number of 4408 sessions currently attached to the subscription. 4410 13.6.3.2.1. Meta-Procedure Specifications 4412 13.6.3.2.1.1. wamp.subscription.list 4414 Retrieves subscription IDs listed according to match policies. 4416 *Arguments* 4418 o None 4420 *Results* 4422 o "SubscriptionLists|dict": A dictionary with a list of subscription 4423 IDs for each match policy. 4425 *Object Schemas* 4427 SubscriptionLists := 4428 { 4429 "exact": subscription_ids|list, 4430 "prefix": subscription_ids|list, 4431 "wildcard": subscription_ids|list 4432 } 4434 See Section 13.6.4 for information on match policies. 4436 13.6.3.2.1.2. wamp.subscription.lookup 4438 Obtains the subscription (if any) managing a topic, according to some 4439 match policy. 4441 *Arguments* 4443 o "topic|uri": The URI of the topic. 4445 o (Optional) "options|dict": Same options as when subscribing to a 4446 topic. 4448 *Results* 4450 o (Nullable) "subscription|id": The ID of the subscription managing 4451 the topic, if found, or null. 4453 13.6.3.2.1.3. wamp.subscription.match 4455 Retrieves a list of IDs of subscriptions matching a topic URI, 4456 irrespective of match policy. 4458 *Arguments* 4460 o "topic|uri": The topic to match. 4462 *Results* 4464 o (Nullable) "subscription_ids|list": A list of all matching 4465 subscription IDs, or null. 4467 13.6.3.2.1.4. wamp.subscription.get 4469 Retrieves information on a particular subscription. 4471 *Arguments* 4473 o "subscription|id": The ID of the subscription to retrieve. 4475 *Results* 4477 o "SubscriptionDetails|dict": Details on the subscription. 4479 *Error URIs* 4481 o "wamp.error.no_such_subscription": No subscription with the given 4482 ID exists on the router. 4484 *Object Schemas* 4486 SubscriptionDetails := 4487 { 4488 "id": subscription|id, 4489 "created": time_created|iso_8601_string, 4490 "uri": topic|uri, 4491 "match": match_policy|string 4492 } 4494 See Section 13.6.4 for information on match policies. 4496 13.6.3.2.1.5. wamp.subscription.list_subscribers 4498 Retrieves a list of session IDs for sessions currently attached to 4499 the subscription. 4501 *Arguments* 4503 o "subscription|id": The ID of the subscription to get subscribers 4504 for. 4506 *Results* 4508 o "subscribers_ids|list": A list of WAMP session IDs of subscribers 4509 currently attached to the subscription. 4511 *Error URIs* 4513 o "wamp.error.no_such_subscription": No subscription with the given 4514 ID exists on the router. 4516 13.6.3.2.1.6. wamp.subscription.count_subscribers 4518 Obtains the number of sessions currently attached to a subscription. 4520 *Arguments* 4522 o "subscription|id": The ID of the subscription to get the number of 4523 subscribers for. 4525 *Results* 4527 o "count|int": The number of sessions currently attached to a 4528 subscription. 4530 *Error URIs* 4531 o "wamp.error.no_such_subscription": No subscription with the given 4532 ID exists on the router. 4534 13.6.4. Pattern-based Subscriptions 4536 13.6.4.1. Introdution 4538 By default, _Subscribers_ subscribe to topics with *exact matching 4539 policy*. That is an event will only be dispatched to a _Subscriber_ 4540 by the _Broker_ if the topic published to ("PUBLISH.Topic") _exactly_ 4541 matches the topic subscribed to ("SUBSCRIBE.Topic"). 4543 A _Subscriber_ might want to subscribe to topics based on a 4544 _pattern_. This can be useful to reduce the number of individual 4545 subscriptions to be set up and to subscribe to topics the 4546 _Subscriber_ is not aware of at the time of subscription, or which do 4547 not yet exist at this time. 4549 If the _Broker_ and the _Subscriber_ support *pattern-based 4550 subscriptions*, this matching can happen by 4552 o prefix-matching policy 4554 o wildcard-matching policy 4556 13.6.4.2. Prefix Matching 4558 A _Subscriber_ requests *prefix-matching policy* with a subscription 4559 request by setting 4561 SUBSCRIBE.Options.match|string := "prefix" 4563 _Example_ 4565 [ 4566 32, 4567 912873614, 4568 { 4569 "match": "prefix" 4570 }, 4571 "com.myapp.topic.emergency" 4572 ] 4574 When a *prefix-matching policy* is in place, any event with a topic 4575 that has "SUBSCRIBE.Topic" as a _prefix_ will match the subscription, 4576 and potentially be delivered to _Subscribers_ on the subscription. 4578 In the above example, events with "PUBLISH.Topic" 4579 o "com.myapp.topic.emergency.11" 4581 o "com.myapp.topic.emergency-low" 4583 o "com.myapp.topic.emergency.category.severe" 4585 o "com.myapp.topic.emergency" 4587 will all apply for dispatching. An event with "PUBLISH.Topic" e.g. 4588 "com.myapp.topic.emerge" will not apply. 4590 13.6.4.3. Wildcard Matching 4592 A _Subscriber_ requests *wildcard-matching policy* with a 4593 subscription request by setting 4595 SUBSCRIBE.Options.match|string := "wildcard" 4597 Wildcard-matching allows to provide wildcards for *whole* URI 4598 components. 4600 _Example_ 4602 [ 4603 32, 4604 912873614, 4605 { 4606 "match": "wildcard" 4607 }, 4608 "com.myapp..userevent" 4609 ] 4611 In above subscription request, the 3rd URI component is empty, which 4612 signals a wildcard in that URI component position. In this example, 4613 events with "PUBLISH.Topic" 4615 o "com.myapp.foo.userevent" 4617 o "com.myapp.bar.userevent" 4619 o "com.myapp.a12.userevent" 4621 will all apply for dispatching. Events with "PUBLISH.Topic" 4623 o "com.myapp.foo.userevent.bar" 4625 o "com.myapp.foo.user" 4626 o "com.myapp2.foo.userevent" 4628 will not apply for dispatching. 4630 13.6.4.4. General 4632 13.6.4.4.1. No set semantics 4634 Since each _Subscriber's_ subscription "stands on its own", there is 4635 no _set semantics_ implied by pattern-based subscriptions. 4637 E.g. a _Subscriber_ cannot subscribe to a broad pattern, and then 4638 unsubscribe from a subset of that broad pattern to form a more 4639 complex subscription. Each subscription is separate. 4641 13.6.4.4.2. Events matching multiple subscriptions 4643 When a single event matches more than one of a _Subscriber's_ 4644 subscriptions, the event will be delivered for each subscription. 4646 The _Subscriber_ can detect the delivery of that same event on 4647 multiple subscriptions via "EVENT.PUBLISHED.Publication", which will 4648 be identical. 4650 13.6.4.4.3. Concrete topic published to 4652 If a subscription was established with a pattern-based matching 4653 policy, a _Broker_ MUST supply the original "PUBLISH.Topic" as 4654 provided by the _Publisher_ in 4656 EVENT.Details.topic|uri 4658 to the _Subscribers_. 4660 _Example_ 4662 [ 4663 36, 4664 5512315355, 4665 4429313566, 4666 { 4667 "topic": "com.myapp.topic.emergency.category.severe" 4668 }, 4669 ["Hello, world!"] 4670 ] 4672 13.6.4.5. Feature Announcement 4674 Support for this feature MUST be announced by _Subscribers_ ("role := 4675 "subscriber"") and _Brokers_ ("role := "broker"") via 4677 HELLO.Details.roles..features. 4678 pattern_based_subscription|bool := true 4680 13.6.5. Sharded Subscriptions 4682 Feature status: *alpha* 4684 Support for this feature MUST be announced by _Publishers_ ("role := 4685 "publisher""), _Subscribers_ ("role := "subscriber"") and _Brokers_ 4686 ("role := "broker"") via 4688 HELLO.Details.roles..features.shareded_subscriptions| 4689 bool := true 4691 Resource keys: "PUBLISH.Options.rkey|string" is a stable, technical 4692 *resource key*. 4694 E.g. if your sensor has a unique serial identifier, you can use 4695 that. 4697 _Example_ 4699 [16, 239714735, {"rkey": "sn239019"}, "com.myapp.sensor.sn239019. 4700 temperature", [33.9]] 4702 Node keys: "SUBSCRIBE.Options.nkey|string" is a stable, technical 4703 *node key*. 4705 E.g. if your backend process runs on a dedicated host, you can use 4706 its hostname. 4708 _Example_ 4710 [32, 912873614, {"match": "wildcard", "nkey": "node23"}, 4711 "com.myapp.sensor..temperature"] 4713 13.6.6. Event History 4715 13.6.6.1. Feature Definition 4717 Instead of complex QoS for message delivery, a _Broker_ may provide 4718 _message history_. A _Subscriber_ is responsible to handle overlaps 4719 (duplicates) when it wants "exactly-once" message processing across 4720 restarts. 4722 The _Broker_ may allow for configuration on a per-topic basis. 4724 The event history may be transient or persistent message history 4725 (surviving _Broker_ restarts). 4727 A _Broker_ that implements _event history_ must (also) announce role 4728 "HELLO.roles.callee", indicate "HELLO.roles.broker.history == 1" and 4729 provide the following (builtin) procedures. 4731 A _Caller_ can request message history by calling the _Broker_ 4732 procedure 4734 wamp.topic.history.last 4736 with "Arguments = [topic|uri, limit|integer]" where 4738 o "topic" is the topic to retrieve event history for 4740 o "limit" indicates the number of last N events to retrieve 4742 or by calling 4744 wamp.topic.history.since 4746 with "Arguments = [topic|uri, timestamp|string]" where 4748 o "topic" is the topic to retrieve event history for 4750 o "timestamp" indicates the UTC timestamp since when to retrieve the 4751 events in the ISO-8601 format "yyyy-MM-ddThh:mm:ss:SSSZ" (e.g. 4752 ""2013-12-21T13:43:11:000Z"") 4754 or by calling 4756 wamp.topic.history.after 4758 with "Arguments = [topic|uri, publication|id]" 4760 o "topic" is the topic to retrieve event history for 4762 o "publication" is the id of an event which marks the start of the 4763 events to retrieve from history 4765 _FIXME_ 4766 1. Should we use "topic|uri" or "subscription|id" in "Arguments"? 4768 * Since we need to be able to get history for pattern-based 4769 subscriptions as well, a subscription|id makes more sense: 4770 create pattern-based subscription, then get the event history 4771 for this. 4773 * The only restriction then is that we may not get event history 4774 without a current subscription covering the events. This is a 4775 minor inconvenience at worst. 4777 2. Can "wamp.topic.history.after" be implemented (efficiently) at 4778 all? 4780 3. How does that interact with pattern-based subscriptions? 4782 4. The same question as with the subscriber lists applies where: to 4783 stay within our separation of roles, we need a broker + a 4784 separate peer which implements the callee role. Here we do not 4785 have a mechanism to get the history from the broker. 4787 13.6.6.2. Feature Announcement 4789 Support for this feature MUST be announced by _Subscribers_ ("role := 4790 "subscriber"") and _Brokers_ ("role := "broker"") via 4792 HELLO.Details.roles..features.event_history|bool := true 4794 13.6.7. Registration Revocation 4796 13.6.7.1. Feature Definition 4798 Actively and forcefully revoke a previously granted subscription from 4799 a session. 4801 13.6.7.2. Feature Announcement 4803 13.6.8. Topic Reflection 4805 o see *Procedure Reflection* for now 4807 13.7. Other Advanced Features 4809 13.7.1. Session Meta API 4810 13.7.1.1. Introduction 4812 WAMP enables the monitoring of when sessions join a realm on the 4813 router or when they leave it via *Session Meta Events*. It also 4814 allows retrieving information about currently connected sessions via 4815 *Session Meta Procedures*. 4817 Meta events are created by the router itself. This means that the 4818 events, as well as the data received when calling a meta procedure, 4819 can be accorded the same trust level as the router. 4821 Note that an implementation that only supports a _Broker_ or 4822 _Dealer_ role, not both at the same time, essentially cannot offer 4823 the *Session Meta API*, as it requires both roles to support this 4824 feature. 4826 13.7.1.2. Session Meta Events 4828 A client can subscribe to the following session meta-events, which 4829 cover the lifecycle of a session: 4831 o "wamp.session.on_join": Fired when a session joins a realm on the 4832 router. 4834 o "wamp.session.on_leave": Fired when a session leaves a realm on 4835 the router or is disconnected. 4837 *Session Meta Events* MUST be dispatched by the _Router_ to the same 4838 realm as the WAMP session which triggered the event. 4840 13.7.1.2.1. wamp.session.on_join 4842 Fired when a session joins a realm on the router. The event payload 4843 consists of a single positional argument "details|dict": 4845 o "session|id" - The session ID of the session that joined 4847 o "authid|string" - The authentication ID of the session that joined 4849 o "authrole|string" - The authentication role of the session that 4850 joined 4852 o "authmethod|string" - The authentication method that was used for 4853 authentication the session that joined 4855 o "authprovider|string"- The provider that performed the 4856 authentication of the session that joined 4858 o "transport|dict" - Optional, implementation defined information 4859 about the WAMP transport the joined session is running over. 4861 See *Authentication* for a description of the "authid", 4862 "authrole", "authmethod" and "authprovider" properties. 4864 13.7.1.2.2. wamp.session.on_leave 4866 Fired when a session leaves a realm on the router or is disconnected. 4867 The event payload consists of a single positional argument 4868 "session|id" with the session ID of the session that left. 4870 13.7.1.3. Session Meta Procedures 4872 A client can actively retrieve information about sessions via the 4873 following meta-procedures: 4875 o "wamp.session.count": Obtains the number of sessions currently 4876 attached to the realm. 4878 o "wamp.session.list": Retrieves a list of the session IDs for all 4879 sessions currently attached to the realm. 4881 o "wamp.session.get": Retrieves information on a specific session. 4883 Session meta procedures MUST be registered by the _Router_ on the 4884 same realm as the WAMP session about which information is retrieved. 4886 13.7.1.3.1. wamp.session.count 4888 Obtains the number of sessions currently attached to the realm: 4890 *Positional arguments* 4892 1. "filter_authroles|list[string]" - Optional filter: if provided, 4893 only count sessions with an "authrole" from this list. 4895 *Positional results* 4897 1. "count|int" - The number of sessions currently attached to the 4898 realm. 4900 13.7.1.3.2. wamp.session.list 4902 Retrieves a list of the session IDs for all sessions currently 4903 attached to the realm. 4905 *Positional arguments* 4906 1. "filter_authroles|list[string]" - Optional filter: if provided, 4907 only count sessions with an "authrole" from this list. 4909 *Positional results* 4911 1. "session_ids|list" - List of WAMP session IDs (order undefined). 4913 13.7.1.3.3. wamp.session.get 4915 Retrieves information on a specific session. 4917 *Positional arguments* 4919 1. "session|id" - The session ID of the session to retrieve details 4920 for. 4922 *Positional results* 4924 1. "details|dict" - Information on a particular session: 4926 * "session|id" - The session ID of the session that joined 4928 * "authid|string" - The authentication ID of the session that 4929 joined 4931 * "authrole|string" - The authentication role of the session 4932 that joined 4934 * "authmethod|string" - The authentication method that was used 4935 for authentication the session that joined 4937 * "authprovider|string"- The provider that performed the 4938 authentication of the session that joined 4940 * "transport|dict" - Optional, implementation defined 4941 information about the WAMP transport the joined session is 4942 running over. 4944 See *Authentication* for a description of the "authid", 4945 "authrole", "authmethod" and "authprovider" properties. 4947 *Errors* 4949 o "wamp.error.no_such_session" - No session with the given ID exists 4950 on the router. 4952 13.7.1.4. Feature Announcement 4954 Support for this feature MUST be announced by *both* _Dealers_ and 4955 _Brokers_ via: 4957 HELLO.Details.roles..features. 4958 session_meta_api|bool := true 4960 *Example* 4962 Here is a "WELCOME" message from a _Router_ with support for both the 4963 _Broker_ and _Dealer_ role, and with support for *Session Meta API*: 4965 [ 4966 2, 4967 4580268554656113, 4968 { 4969 "authid":"OL3AeppwDLXiAAPbqm9IVhnw", 4970 "authrole": "anonymous", 4971 "authmethod": "anonymous", 4972 "roles": { 4973 "broker": { 4974 "features": { 4975 "session_meta_api": true 4976 } 4977 }, 4978 "dealer": { 4979 "features": { 4980 "session_meta_api": true 4981 } 4982 } 4983 } 4984 } 4985 ] 4987 Note in particular that the feature is announced on both the 4988 _Broker_ and the _Dealer_ roles. 4990 13.7.2. Authentication 4992 Authentication is a complex area. 4994 Some applications might want to leverage authentication information 4995 coming from the transport underlying WAMP, e.g. HTTP cookies or TLS 4996 certificates. 4998 Some transports might imply trust or implicit authentication by their 4999 very nature, e.g. Unix domain sockets with appropriate file system 5000 permissions in place. 5002 Other application might want to perform their own authentication 5003 using external mechanisms (completely outside and independent of 5004 WAMP). 5006 Some applications might want to perform their own authentication 5007 schemes by using basic WAMP mechanisms, e.g. by using application- 5008 defined remote procedure calls. 5010 And some applications might want to use a transport independent 5011 scheme, nevertheless predefined by WAMP. 5013 13.7.2.1. WAMP-level Authentication 5015 The message flow between Clients and Routers for establishing and 5016 tearing down sessions MAY involve the following messages which 5017 authenticate a session: 5019 1. "CHALLENGE" 5021 2. "AUTHENTICATE" 5023 ,------. ,------. 5024 |Client| |Router| 5025 `--+---' `--+---' 5026 | HELLO | 5027 | ----------------> 5028 | | 5029 | CHALLENGE | 5030 | <---------------- 5031 | | 5032 | AUTHENTICATE | 5033 | ----------------> 5034 | | 5035 | WELCOME or ABORT| 5036 | <---------------- 5037 ,--+---. ,--+---. 5038 |Client| |Router| 5039 `------' `------' 5041 Concrete use of "CHALLENGE" and "AUTHENTICATE" messages depends on 5042 the specific authentication method. 5044 See Section 13.7.2.3 or Section 13.7.2.4 for the use in these 5045 authentication methods. 5047 If two-factor authentication is desired, then two subsequent rounds 5048 of "CHALLENGE" and "RESPONSE" may be employed. 5050 13.7.2.1.1. CHALLENGE 5052 An authentication MAY be required for the establishment of a session. 5053 Such requirement MAY be based on the "Realm" the connection is 5054 requested for. 5056 To request authentication, the Router MUST send a "CHALLENGE" message 5057 to the _Endpoint_. 5059 [CHALLENGE, AuthMethod|string, Extra|dict] 5061 13.7.2.1.2. AUTHENTICATE 5063 In response to a "CHALLENGE" message, the Client MUST send an 5064 "AUTHENTICATION" message. 5066 [AUTHENTICATE, Signature|string, Extra|dict] 5068 If the authentication succeeds, the Router MUST send a "WELCOME" 5069 message, else it MUST send an "ABORT" message. 5071 13.7.2.2. Transport-level Authentication 5073 13.7.2.2.1. Cookie-based Authentication 5075 When running WAMP over WebSocket, the transport provides HTTP client 5076 cookies during the WebSocket opening handshake. The cookies can be 5077 used to authenticate one peer (the client) against the other (the 5078 server). The other authentication direction cannot be supported by 5079 cookies. 5081 This transport-level authentication information may be forward to the 5082 WAMP level within "HELLO.Details.transport.auth|any" in the client- 5083 to-server direction. 5085 13.7.2.2.2. TLS Certificate Authentication 5087 When running WAMP over a TLS (either secure WebSocket or raw TCP) 5088 transport, a peer may authenticate to the other via the TLS 5089 certificate mechanism. A server might authenticate to the client, 5090 and a client may authenticate to the server (TLS client-certificate 5091 based authentication). 5093 This transport-level authentication information may be forward to the 5094 WAMP level within "HELLO.Details.transport.auth|any" in both 5095 directions (if available). 5097 13.7.2.3. Challenge Response Authentication 5099 WAMP Challenge-Response ("WAMP-CRA") authentication is a simple, 5100 secure authentication mechanism using a shared secret. The client 5101 and the server share a secret. The secret never travels the wire, 5102 hence WAMP-CRA can be used via non-TLS connections. The actual pre- 5103 sharing of the secret is outside the scope of the authentication 5104 mechanism. 5106 A typical authentication begins with the client sending a "HELLO" 5107 message specifying the "wampcra" method as (one of) the 5108 authentication methods: 5110 [1, "realm1", 5111 { 5112 "roles": ..., 5113 "authmethods": ["wampcra"], 5114 "authid": "peter" 5115 } 5116 ] 5118 The "HELLO.Details.authmethods|list" is used by the client to 5119 announce the authentication methods it is prepared to perform. For 5120 WAMP-CRA, this MUST include ""wampcra"". 5122 The "HELLO.Details.authid|string" is the authentication ID (e.g. 5123 username) the client wishes to authenticate as. For WAMP-CRA, this 5124 MUST be provided. 5126 If the server is unwilling or unable to perform WAMP-CRA 5127 authentication, it MAY either skip forward trying other 5128 authentication methods (if the client announced any) or send an 5129 "ABORT" message. 5131 If the server is willing to let the client authenticate using WAMP- 5132 CRA, and the server recognizes the provided "authid", it MUST send a 5133 "CHALLENGE" message: 5135 [4, "wampcra", 5136 { 5137 "challenge": "{ \"nonce\": \"LHRTC9zeOIrt_9U3\", 5138 \"authprovider\": \"userdb\", \"authid\": \"peter\", 5139 \"timestamp\": \"2014-06-22T16:36:25.448Z\", 5140 \"authrole\": \"user\", \"authmethod\": \"wampcra\", 5141 \"session\": 3251278072152162}" 5142 } 5143 ] 5145 The "CHALLENGE.Details.challenge|string" is a string the client needs 5146 to create a signature for. The string MUST BE a JSON serialized 5147 object which MUST contain: 5149 1. "authid|string": The authentication ID the client will be 5150 authenticated as when the authentication succeeds. 5152 2. "authrole|string": The authentication role the client will be 5153 authenticated as when the authentication succeeds. 5155 3. "authmethod|string": The authentication methods, here ""wampcra"" 5157 4. "authprovider|string": The actual provider of authentication. 5158 For WAMP-CRA, this can be freely chosen by the app, e.g. 5159 "userdb". 5161 5. "nonce|string": A random value. 5163 6. "timestamp|string": The UTC timestamp (ISO8601 format) the 5164 authentication was started, e.g. "2014-06-22T16:51:41.643Z". 5166 7. "session|int": The WAMP session ID that will be assigned to the 5167 session once it is authenticated successfully. 5169 The client needs to compute the signature as follows: 5171 signature := HMAC[SHA256]_{secret} (challenge) 5173 That is, compute the HMAC-SHA256 using the shared "secret" over the 5174 "challenge". 5176 After computing the signature, the client will send an "AUTHENTICATE" 5177 message containing the signature: 5179 [5, "gir1mSx+deCDUV7wRM5SGIn/+R/ClqLZuH4m7FJeBVI=", {}] 5181 The server will then check if 5182 o the signature matches the one expected 5184 o the "AUTHENTICATE" message was sent in due time 5186 If the authentication succeeds, the server will finally respond with 5187 a "WELCOME" message: 5189 [2, 3251278072152162, 5190 { 5191 "authid": "peter", 5192 "authrole": "user", 5193 "authmethod": "wampcra", 5194 "authprovider": "userdb", 5195 "roles": ... 5196 } 5197 ] 5199 The "WELCOME.Details" again contain the actual authentication 5200 information active. 5202 If the authentication fails, the server will response with an "ABORT" 5203 message. 5205 13.7.2.3.1. Server-side Verification 5207 The challenge sent during WAMP-CRA contains 5209 1. random information (the "nonce") to make WAMP-CRA robust against 5210 replay attacks 5212 2. timestamp information (the "timestamp") to allow WAMP-CRA timeout 5213 on authentication requests that took too long 5215 3. session information (the "session") to bind the authentication to 5216 a WAMP session ID 5218 4. all the authentication information that relates to authorization 5219 like "authid" and "authrole" 5221 13.7.2.3.2. Three-legged Authentication 5223 The signing of the challenge sent by the server usually is done 5224 directly on the client. However, this is no strict requirement. 5226 E.g. a client might forward the challenge to another party (hence the 5227 "three-legged") for creating the signature. This can be used when 5228 the client was previously already authenticated to that third party, 5229 and WAMP-CRA should run piggy packed on that authentication. 5231 The third party would, upon receiving a signing request, simply check 5232 if the client is already authenticated, and if so, create a signature 5233 for WAMP-CRA. 5235 In this case, the secret is actually shared between the WAMP server 5236 who wants to authenticate clients using WAMP-CRA and the third party 5237 server, who shares a secret with the WAMP server. 5239 This scenario is also the reason the challenge sent with WAMP-CRA is 5240 not simply a random value, but a JSON serialized object containing 5241 sufficient authentication information for the thrid party to check. 5243 13.7.2.3.3. Password Salting 5245 WAMP-CRA operates using a shared secret. While the secret is never 5246 sent over the wire, a shared secret often requires storage of that 5247 secret on the client and the server - and storing a password verbatim 5248 (unencrypted) is not recommended in general. 5250 WAMP-CRA allows the use of salted passwords following the PBKDF2 [5] 5251 key derivation scheme. With salted passwords, the password itself is 5252 never stored, but only a key derived from the password and a password 5253 salt. This derived key is then practically working as the new shared 5254 secret. 5256 When the password is salted, the server will during WAMP-CRA send a 5257 "CHALLENGE" message containing additional information: 5259 [4, "wampcra", 5260 { 5261 "challenge": "{ \"nonce\": \"LHRTC9zeOIrt_9U3\", 5262 \"authprovider\": \"userdb\", \"authid\": \"peter\", 5263 \"timestamp\": \"2014-06-22T16:36:25.448Z\", 5264 \"authrole\": \"user\", \"authmethod\": \"wampcra\", 5265 \"session\": 3251278072152162}", 5266 "salt": "salt123", 5267 "keylen": 32, 5268 "iterations": 1000 5269 } 5270 ] 5272 The "CHALLENGE.Details.salt|string" is the password salt in use. The 5273 "CHALLENGE.Details.keylen|int" and "CHALLENGE.Details.iterations|int" 5274 are parameters for the PBKDF2 algorithm. 5276 13.7.2.4. Ticket-based Authentication 5278 With _Ticket-based authentication_, the client needs to present the 5279 server an authentication "ticket" - some magic value to authenticate 5280 itself to the server. 5282 This "ticket" could be a long-lived, pre-agreed secret (e.g. a user 5283 password) or a short-lived authentication token (like a Kerberos 5284 token). WAMP does not care or interpret the ticket presented by the 5285 client. 5287 Caution: This scheme is extremely simple and flexible, but the 5288 resulting security may be limited. E.g., the ticket value will be 5289 sent over the wire. If the transport WAMP is running over is not 5290 encrypted, a man-in-the-middle can sniff and possibly hijack the 5291 ticket. If the ticket value is reused, that might enable replay 5292 attacks. 5294 A typical authentication begins with the client sending a "HELLO" 5295 message specifying the "ticket" method as (one of) the authentication 5296 methods: 5298 [1, "realm1", 5299 { 5300 "roles": ..., 5301 "authmethods": ["ticket"], 5302 "authid": "joe" 5303 } 5304 ] 5306 The "HELLO.Details.authmethods|list" is used by the client to 5307 announce the authentication methods it is prepared to perform. For 5308 Ticket-based, this MUST include ""ticket"". 5310 The "HELLO.Details.authid|string" is the authentication ID (e.g. 5311 username) the client wishes to authenticate as. For Ticket-based 5312 authentication, this MUST be provided. 5314 If the server is unwilling or unable to perform Ticket-based 5315 authentication, it'll either skip forward trying other authentication 5316 methods (if the client announced any) or send an "ABORT" message. 5318 If the server is willing to let the client authenticate using a 5319 ticket and the server recognizes the provided "authid", it'll send a 5320 "CHALLENGE" message: 5322 [4, "ticket", {}] 5324 The client will send an "AUTHENTICATE" message containing a ticket: 5326 [5, "secret!!!", {}] 5328 The server will then check if the ticket provided is permissible (for 5329 the "authid" given). 5331 If the authentication succeeds, the server will finally respond with 5332 a "WELCOME" message: 5334 [2, 3251278072152162, 5335 { 5336 "authid": "joe", 5337 "authrole": "user", 5338 "authmethod": "ticket", 5339 "authprovider": "static", 5340 "roles": ... 5341 } 5342 ] 5344 where 5346 1. "authid|string": The authentication ID the client was (actually) 5347 authenticated as. 5349 2. "authrole|string": The authentication role the client was 5350 authenticated for. 5352 3. "authmethod|string": The authentication method, here ""ticket"" 5354 4. "authprovider|string": The actual provider of authentication. 5355 For Ticket-based authentication, this can be freely chosen by the 5356 app, e.g. "static" or "dynamic". 5358 The "WELCOME.Details" again contain the actual authentication 5359 information active. If the authentication fails, the server will 5360 response with an "ABORT" message. 5362 13.7.3. Alternative Transports 5364 The only requirements that WAMP expects from a transport are: the 5365 transport must be message-based, bidirectional, reliable and ordered. 5366 This allows WAMP to run over different transports without any impact 5367 at the application layer. 5369 Besides the WebSocket transport, the following WAMP transports are 5370 currently specified: 5372 o Section 13.7.3.1 5374 o Section 13.7.3.2 5376 o Section 13.7.3.3 5378 o Section 13.7.3.4 5380 Other transports such as HTTP 2.0 ("SPDY") or UDP might be defined 5381 in the future. 5383 13.7.3.1. RawSocket Transport 5385 *WAMP-over-RawSocket* is an (alternative) transport for WAMP that 5386 uses length-prefixed, binary messages - a message framing different 5387 from WebSocket. 5389 Compared to WAMP-over-WebSocket, WAMP-over-RawSocket is simple to 5390 implement, since there is no need to implement the WebSocket protocol 5391 which has some features that make it non-trivial (like a full HTTP- 5392 based opening handshake, message fragmentation, masking and variable 5393 length integers). 5395 WAMP-over-RawSocket has even lower overhead than WebSocket, which can 5396 be desirable in particular when running on local connections like 5397 loopback TCP or Unix domain sockets. It is also expected to allow 5398 implementations in microcontrollers in under 2KB RAM. 5400 WAMP-over-RawSocket can run over TCP, TLS, Unix domain sockets or any 5401 reliable streaming underlying transport. When run over TLS on the 5402 standard port for secure HTTPS (443), it is also able to traverse 5403 most locked down networking environments such as enterprise or mobile 5404 networks (unless man-in-the-middle TLS intercepting proxies are in 5405 use). 5407 However, WAMP-over-RawSocket cannot be used with Web browser clients, 5408 since browsers do not allow raw TCP connections. Browser extensions 5409 would do, but those need to be installed in a browser. WAMP-over- 5410 RawSocket also (currently) does not support transport-level 5411 compression as WebSocket does provide ("permessage-deflate" WebSocket 5412 extension). 5414 13.7.3.1.1. Endianess 5416 WAMP-over-RawSocket uses _network byte order_ ("big-endian"). That 5417 means, given a unsigned 32 bit integer 5419 0x 11 22 33 44 5421 the first octet sent out to (or received from) the wire is "0x11" and 5422 the last octet sent out (or received) is "0x44". 5424 Here is how you would convert octets received from the wire into an 5425 integer in Python: 5427 5428 import struct 5430 octets_received = b"\x11\x22\x33\x44" 5431 i = struct.unpack(">L", octets_received)[0] 5432 5434 The integer received has the value "287454020". 5436 And here is how you would send out an integer to the wire in Python: 5438 5439 octets_to_be_send = struct.pack(">L", i) 5440 5442 The octets to be sent are "b"\x11\x22\x33\x44"". 5444 13.7.3.1.2. Handshake 5446 *Client-to-Router Request* 5448 WAMP-over-RawSocket starts with a handshake where the client 5449 connecting to a router sends 4 octets: 5451 MSB LSB 5452 31 0 5453 0111 1111 LLLL SSSS RRRR RRRR RRRR RRRR 5455 The _first octet_ is a magic octet with value "0x7F". This value is 5456 chosen to avoid any possible collision with the first octet of a 5457 valid HTTP request (see here [6] and here [7]). No valid HTTP 5458 request can have "0x7F" as its first octet. 5460 By using a magic first octet that cannot appear in a regular HTTP 5461 request, WAMP-over-RawSocket can be run e.g. on the same TCP 5462 listening port as WAMP-over-WebSocket or WAMP-over-LongPoll. 5464 The _second octet_ consists of a 4 bit "LENGTH" field and a 4 bit 5465 "SERIALIZER" field. 5467 The "LENGTH" value is used by the _Client_ to signal the *maximum 5468 message length* of messages it is willing to *receive*. When the 5469 handshake completes successfully, a _Router_ MUST NOT send messages 5470 larger than this size. 5472 The possible values for "LENGTH" are: 5474 0: 2**9 octets 5475 1: 2**10 octets 5476 ... 5477 15: 2**24 octets 5479 This means a _Client_ can choose the maximum message length between 5480 *512* and *16M* octets. 5482 The "SERIALIZER" value is used by the _Client_ to request a specific 5483 serializer to be used. When the handshake completes successfully, 5484 the _Client_ and _Router_ will use the serializer requested by the 5485 _Client_. 5487 The possible values for "SERIALIZER" are: 5489 0: illegal 5490 1: JSON 5491 2: MsgPack 5492 3 - 15: reserved for future serializers 5494 Here is a Python program that prints all (currently) permissible 5495 values for the _second octet_: 5497 5498 SERMAP = { 5499 1: 'json', 5500 2: 'msgpack' 5501 } 5503 ## map serializer / max. msg length to RawSocket handshake request 5504 ## or success reply (2nd octet) 5505 ## 5506 for ser in SERMAP: 5507 for l in range(16): 5508 octet_2 = (l << 4) | ser 5509 print("serializer: {}, maxlen: {} => 5510 0x{:02x}".format(SERMAP[ser], 2 ** (l + 9), octet_2)) 5511 5513 The _third and forth octet_ are *reserved* and MUST be all zeros for 5514 now. 5516 *Router-to-Client Reply* 5517 After a _Client_ has connected to a _Router_, the _Router_ will first 5518 receive the 4 octets handshake request from the _Client_. 5520 If the _first octet_ differs from "0x7F", it is not a WAMP-over- 5521 RawSocket request. Unless the _Router_ also supports other 5522 transports on the connecting port (such as WebSocket or LongPoll), 5523 the _Router_ MUST *fail the connection*. 5525 Here is an example of how a _Router_ could parse the _second octet_ 5526 in a _Clients_ handshake request: 5528 5529 ## map RawSocket handshake request (2nd octet) to 5530 ## serializer / max. msg length 5531 ## 5532 for i in range(256): 5533 ser_id = i & 0x0f 5534 if ser_id != 0: 5535 ser = SERMAP.get(ser_id, 'currently undefined') 5536 maxlen = 2 ** ((i >> 4) + 9) 5537 print("{:02x} => serializer: {}, maxlen: {}". 5538 format(i, ser, maxlen)) 5539 else: 5540 print("fail the connection: illegal serializer value") 5541 5543 When the _Router_ is willing to speak the serializer requested by the 5544 _Client_, it will answer with a 4 octets response of identical 5545 structure as the _Client_ request: 5547 MSB LSB 5548 31 0 5549 0111 1111 LLLL SSSS RRRR RRRR RRRR RRRR 5551 Again, the _first octet_ MUST be the value "0x7F". The _third and 5552 forth octets_ are reserved and MUST be all zeros for now. 5554 In the _second octet_, the _Router_ MUST echo the serializer value in 5555 "SERIALIZER" as requested by the _Client_. 5557 Similar to the _Client_, the _Router_ sets the "LENGTH" field to 5558 request a limit on the length of messages sent by the _Client_. 5560 During the connection, _Router_ MUST NOT send messages to the 5561 _Client_ longer than the "LENGTH" requested by the _Client_, and the 5562 _Client_ MUST NOT send messages larger than the maximum requested by 5563 the _Router_ in it's handshake reply. 5565 If a message received during a connection exceeds the limit 5566 requested, a _Peer_ MUST *fail the connection*. 5568 When the _Router_ is unable to speak the serializer requested by the 5569 _Client_, or it is denying the _Client_ for other reasons, the 5570 _Router_ replies with an error: 5572 MSB LSB 5573 31 0 5574 0111 1111 EEEE 0000 RRRR RRRR RRRR RRRR 5576 An error reply has 4 octets: the _first octet_ is again the magic 5577 "0x7F", and the _third and forth octet_ are reserved and MUST all be 5578 zeros for now. 5580 The _second octet_ has its lower 4 bits zero'ed (which distinguishes 5581 the reply from an success/accepting reply) and the upper 4 bits 5582 encode the error: 5584 0: illegal (must not be used) 5585 1: serializer unsupported 5586 2: maximum message length unacceptable 5587 3: use of reserved bits (unsupported feature) 5588 4: maximum connection count reached 5589 5 - 15: reserved for future errors 5591 Note that the error code "0" MUST NOT be used. This is to allow 5592 storage of error state in a host language variable, while allowing 5593 "0" to signal the current state "no error" 5595 Here is an example of how a _Router_ might create the _second octet_ 5596 in an error response: 5598 5599 ERRMAP = { 5600 0: "illegal (must not be used)", 5601 1: "serializer unsupported", 5602 2: "maximum message length unacceptable", 5603 3: "use of reserved bits (unsupported feature)", 5604 4: "maximum connection count reached" 5605 } 5607 ## map error to RawSocket handshake error reply (2nd octet) 5608 ## 5609 for err in ERRMAP: 5610 octet_2 = err << 4 5611 print("error: {} => 0x{:02x}").format(ERRMAP[err], err) 5612 5614 The _Client_ - after having sent its handshake request - will wait 5615 for the 4 octets from _Router_ handshake reply. 5617 Here is an example of how a _Client_ might parse the _second octet_ 5618 in a _Router_ handshake reply: 5620 5621 ## map RawSocket handshake reply (2nd octet) 5622 ## 5623 for i in range(256): 5624 ser_id = i & 0x0f 5625 if ser_id: 5626 ## verify the serializer is the one we requested! 5627 ## if not, fail the connection! 5628 ser = SERMAP.get(ser_id, 'currently undefined') 5629 maxlen = 2 ** ((i >> 4) + 9) 5630 print("{:02x} => serializer: {}, maxlen: {}". 5631 format(i, ser, maxlen)) 5632 else: 5633 err = i >> 4 5634 print("error: {}".format(ERRMAP.get(err, 5635 'currently undefined'))) 5636 5638 13.7.3.1.3. Serialization 5640 To send a WAMP message, the message is serialized according to the 5641 WAMP serializer agreed in the handshake (e.g. JSON or MsgPack). 5643 The length of the serialized messages in octets MUST NOT exceed the 5644 maximum requested by the _Peer_. 5646 If the serialized length exceed the maximum requested, the WAMP 5647 message can not be sent to the _Peer_. Handling situations like the 5648 latter is left to the implementation. 5650 E.g. a _Router_ that is to forward a WAMP "EVENT" to a _Client_ which 5651 exceeds the maximum length requested by the _Client_ when serialized 5652 might: 5654 o drop the event (not forwarding to that specific client) and track 5655 dropped events 5657 o prohibit publishing to the topic already 5659 o remove the event payload, and send an event with extra information 5660 ("payload_limit_exceeded = true") 5662 13.7.3.1.4. Framing 5664 The serialized octets for a message to be sent are prefixed with 5665 exactly 4 octets. 5667 MSB LSB 5668 31 0 5669 RRRR RTTT LLLL LLLL LLLL LLLL LLLL LLLL 5671 The _first octet_ has the following structure 5673 MSB LSB 5674 7 0 5675 RRRR RTTT 5677 The five bits "RRRRR" are reserved for future use and MUST be all 5678 zeros for now. 5680 The three bits "TTT" encode the type of the transport message: 5682 0: regular WAMP message 5683 1: PING 5684 2: PONG 5685 3-7: reserved 5687 The _three remaining octets_ constitute an unsigned 24 bit integer 5688 that provides the length of transport message payload following, 5689 excluding the 4 octets that constitute the prefix. 5691 For a regular WAMP message ("TTT == 0"), the length is the length of 5692 the serialized WAMP message: the number of octets after serialization 5693 (excluding the 4 octets of the prefix). 5695 For a "PING" message ("TTT == 1"), the length is the length of the 5696 arbitrary payload that follows. A _Peer_ MUST reply to each "PING" 5697 by sending exactly one "PONG" immediately, and the "PONG" MUST echo 5698 back the payload of the "PING" exactly. 5700 For receiving messages with WAMP-over-RawSocket, a _Peer_ will 5701 usually read exactly 4 octets from the incoming stream, decode the 5702 transport level message type and payload length, and then receive as 5703 many octets as the length was giving. 5705 When the transport level message type indicates a regular WAMP 5706 message, the transport level message payload is unserialized 5707 according to the serializer agreed in the handshake and the processed 5708 at the WAMP level. 5710 13.7.3.2. Batched WebSocket Transport for WAMP 5712 _WAMP-over-Batched-WebSocket_ is a variant of WAMP-over-WebSocket 5713 where multiple WAMP messages are sent in one WebSocket message. 5715 Using WAMP message batching can increase wire level efficiency 5716 further. In particular when using TLS and the WebSocket 5717 implementation is forcing every WebSocket message into a new TLS 5718 segment. 5720 WAMP-over-Batched-WebSocket is negotiated between Peers in the 5721 WebSocket opening handshake by agreeing on one of the following 5722 WebSocket subprotocols: 5724 o "wamp.2.json.batched" 5726 o "wamp.2.msgpack.batched" 5728 Batching with JSON works by serializing each WAMP message to JSON as 5729 normally, appending the single ASCII control character "\30" (record 5730 separator [8]) octet "0x1e" to _each_ serialized messages, and 5731 packing a sequence of such serialized messages into a single 5732 WebSocket message: 5734 Serialized JSON WAMP Msg 1 | 0x1e | 5735 Serialized JSON WAMP Msg 2 | 0x1e | ... 5737 Batching with MsgPack works by serializing each WAMP message to 5738 MsgPack as normally, prepending a 32 bit unsigned integer (4 octets 5739 in big-endian byte order) with the length of the serialized MsgPack 5740 message (excluding the 4 octets for the length prefix), and packing a 5741 sequence of such serialized (length-prefixed) messages into a single 5742 WebSocket message: 5744 Length of Msg 1 serialization (uint32) | 5745 serialized MsgPack WAMP Msg 1 | ... 5747 With batched transport, even if only a single WAMP message is to be 5748 sent in a WebSocket message, the (single) WAMP message needs to be 5749 framed as described above. In other words, a single WAMP message is 5750 sent as a batch of length *1*. Sending a batch of length *0* (no WAMP 5751 message) is illegal and a _Peer_ MUST fail the transport upon 5752 receiving such a transport message. 5754 13.7.3.3. A HTTP Longpoll Transport for WAMP 5756 The _Long-Poll Transport_ is able to transmit a WAMP session over 5757 plain old HTTP 1.0/1.1. This is realized by the Client issuing HTTP/ 5758 POSTs requests, one for sending, and one for receiving. Those latter 5759 requests are kept open at the server when there are no messages 5760 currently pending to be received. 5762 *Opening a Session* 5764 With the Long-Poll Transport, a Client opens a new WAMP session by 5765 sending a HTTP/POST request to a well-known URL, e.g. 5767 http://mypp.com/longpoll/open 5769 Here, "http://mypp.com/longpoll" is the base URL for the Long-Poll 5770 Transport and "/open" is a path dedicated for opening new sessions. 5772 The HTTP/POST request SHOULD have a "Content-Type" header set to 5773 "application/json" and MUST have a request body with a JSON document 5774 that is a dictionary: 5776 { 5777 "protocols": ["wamp.2.json"] 5778 } 5780 The (mandatory) "protocols" attribute specifies the protocols the 5781 client is willing to speak. The server will chose one from this list 5782 when establishing the session or fail the request when no protocol 5783 overlap was found. 5785 The valid protocols are: 5787 o "wamp.2.json.batched" 5789 o "wamp.2.json" 5791 o "wamp.2.msgpack.batched" 5793 o "wamp.2.msgpack" 5795 The request path with this and subsequently described HTTP/POST 5796 requests MAY contain a query parameter "x" with some random or 5797 sequentially incremented value: 5799 5800 The value is ignored, but may help in certain situations to 5801 prevent intermediaries from caching the request. 5803 Returned is a JSON document containing a transport ID and the 5804 protocol to speak: 5806 { 5807 "protocol": "wamp.2.json", 5808 "transport": "kjmd3sBLOUnb3Fyr" 5809 } 5811 As an implied side-effect, two HTTP endpoints are created 5813 http://mypp.com/longpoll//receive 5814 http://mypp.com/longpoll//send 5816 where "transport_id" is the transport ID returned from "open", e.g. 5818 http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/receive 5819 http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/send 5821 *Receiving WAMP Messages* 5823 The Client will then issue HTTP/POST requests (with empty request 5824 body) to 5826 http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/receive 5828 When there are WAMP messages pending downstream, a request will 5829 return with a single WAMP message (unbatched modes) or a batch of 5830 serialized WAMP messages (batched mode). 5832 The serialization format used is the one agreed during opening the 5833 session. 5835 The batching uses the same scheme as with "wamp.2.json.batched" and 5836 "wamp.2.msgpack.batched" transport over WebSocket. 5838 Note: In unbatched mode, when there is more than one message 5839 pending, there will be at most one message returned for each 5840 request. The other pending messages must be retrieved by new 5841 requests. With batched mode, all messages pending at request time 5842 will be returned in one batch of messages. 5844 *Sending WAMP Messages* 5846 For sending WAMP messages, the _Client_ will issue HTTP/POST requests 5847 to 5848 http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/send 5850 with request body being a single WAMP message (unbatched modes) or a 5851 batch of serialized WAMP messages (batched mode). 5853 The serialization format used is the one agreed during opening the 5854 session. 5856 The batching uses the same scheme as with "wamp.2.json.batched" and 5857 "wamp.2.msgpack.batched" transport over WebSocket. 5859 Upon success, the request will return with HTTP status code 202 ("no 5860 content"). Upon error, the request will return with HTTP status code 5861 400 ("bad request"). 5863 *Closing a Session* 5865 To orderly close a session, a Client will issue a HTTP/POST to 5867 http://mypp.com/longpoll/kjmd3sBLOUnb3Fyr/close 5869 with an empty request body. Upon success, the request will return 5870 with HTTP status code 202 ("no content"). 5872 13.7.3.4. Multiplexed Transport 5874 A Transport may support the multiplexing of multiple logical 5875 transports over a single "physical" transport. 5877 By using such a Transport, multiple WAMP sessions can be transported 5878 over a single underlying transport at the same time. 5880 As an example, the proposed WebSocket extension "permessage-priority" 5881 [9] would allow creating multiple logical Transports for WAMP over a 5882 single underlying WebSocket connection. 5884 Sessions running over a multiplexed Transport are completely 5885 independent: they get assigned different session IDs, may join 5886 different realms and each session needs to authenticate itself. 5888 Because of above, Multiplexed Transports for WAMP are actually not 5889 detailed in the WAMP spec, but a feature of the transport being used. 5891 Note: Currently no WAMP transport supports multiplexing. The work 5892 on the MUX extension with WebSocket has stalled, and the 5893 "permessage-priority" proposal above is still just a proposal. 5894 However, with RawSocket, we should be able to add multiplexing in 5895 the the future (with downward compatibility). 5897 13.7.3.5. Ticket-based Authentication 5899 With _Ticket-based authentication_, the client needs to present the 5900 server an authentication "ticket" - some magic value to authenticate 5901 itself to the server. 5903 This "ticket" could be a long-lived, pre-agreed secret (e.g. a user 5904 password) or a short-lived authentication token (like a Kerberos 5905 token). WAMP does not care or interpret the ticket presented by the 5906 client. 5908 Caution: This scheme is extremely simple and flexible, but the 5909 resulting security may be limited. E.g., the ticket value will be 5910 sent over the wire. If the transport WAMP is running over is not 5911 encrypted, a man-in-the-middle can sniff and possibly hijack the 5912 ticket. If the ticket value is reused, that might enable replay 5913 attacks. 5915 A typical authentication begins with the client sending a "HELLO" 5916 message specifying the "ticket" method as (one of) the authentication 5917 methods: 5919 [1, "realm1", 5920 { 5921 "roles": ..., 5922 "authmethods": ["ticket"], 5923 "authid": "joe" 5924 } 5925 ] 5927 The "HELLO.Details.authmethods|list" is used by the client to 5928 announce the authentication methods it is prepared to perform. For 5929 Ticket-based, this MUST include ""ticket"". 5931 The "HELLO.Details.authid|string" is the authentication ID (e.g. 5932 username) the client wishes to authenticate as. For Ticket-based 5933 authentication, this MUST be provided. 5935 If the server is unwilling or unable to perform Ticket-based 5936 authentication, it'll either skip forward trying other authentication 5937 methods (if the client announced any) or send an "ABORT" message. 5939 If the server is willing to let the client authenticate using a 5940 ticket and the server recognizes the provided "authid", it'll send a 5941 "CHALLENGE" message: 5943 [4, "ticket", {}] 5945 The client will send an "AUTHENTICATE" message containing a ticket: 5947 [5, "secret!!!", {}] 5949 The server will then check if the ticket provided is permissible (for 5950 the "authid" given). 5952 If the authentication succeeds, the server will finally respond with 5953 a "WELCOME" message: 5955 [2, 3251278072152162, 5956 { 5957 "authid": "joe", 5958 "authrole": "user", 5959 "authmethod": "ticket", 5960 "authprovider": "static", 5961 "roles": ... 5962 } 5963 ] 5965 where 5967 1. "authid|string": The authentication ID the client was (actually) 5968 authenticated as. 5970 2. "authrole|string": The authentication role the client was 5971 authenticated for. 5973 3. "authmethod|string": The authentication method, here ""ticket"" 5975 4. "authprovider|string": The actual provider of authentication. 5976 For Ticket-based authentication, this can be freely chosen by the 5977 app, e.g. "static" or "dynamic". 5979 The "WELCOME.Details" again contain the actual authentication 5980 information active. If the authentication fails, the server will 5981 response with an "ABORT" message. 5983 13.7.3.6. Ticket-based Authentication 5985 With _Ticket-based authentication_, the client needs to present the 5986 server an authentication "ticket" - some magic value to authenticate 5987 itself to the server. 5989 This "ticket" could be a long-lived, pre-agreed secret (e.g. a user 5990 password) or a short-lived authentication token (like a Kerberos 5991 token). WAMP does not care or interpret the ticket presented by the 5992 client. 5994 Caution: This scheme is extremely simple and flexible, but the 5995 resulting security may be limited. E.g., the ticket value will be 5996 sent over the wire. If the transport WAMP is running over is not 5997 encrypted, a man-in-the-middle can sniff and possibly hijack the 5998 ticket. If the ticket value is reused, that might enable replay 5999 attacks. 6001 A typical authentication begins with the client sending a "HELLO" 6002 message specifying the "ticket" method as (one of) the authentication 6003 methods: 6005 [1, "realm1", 6006 { 6007 "roles": ..., 6008 "authmethods": ["ticket"], 6009 "authid": "joe" 6010 } 6011 ] 6013 The "HELLO.Details.authmethods|list" is used by the client to 6014 announce the authentication methods it is prepared to perform. For 6015 Ticket-based, this MUST include ""ticket"". 6017 The "HELLO.Details.authid|string" is the authentication ID (e.g. 6018 username) the client wishes to authenticate as. For Ticket-based 6019 authentication, this MUST be provided. 6021 If the server is unwilling or unable to perform Ticket-based 6022 authentication, it'll either skip forward trying other authentication 6023 methods (if the client announced any) or send an "ABORT" message. 6025 If the server is willing to let the client authenticate using a 6026 ticket and the server recognizes the provided "authid", it'll send a 6027 "CHALLENGE" message: 6029 [4, "ticket", {}] 6031 The client will send an "AUTHENTICATE" message containing a ticket: 6033 [5, "secret!!!", {}] 6035 The server will then check if the ticket provided is permissible (for 6036 the "authid" given). 6038 If the authentication succeeds, the server will finally respond with 6039 a "WELCOME" message: 6041 [2, 3251278072152162, 6042 { 6043 "authid": "joe", 6044 "authrole": "user", 6045 "authmethod": "ticket", 6046 "authprovider": "static", 6047 "roles": ... 6048 } 6049 ] 6051 where 6053 1. "authid|string": The authentication ID the client was (actually) 6054 authenticated as. 6056 2. "authrole|string": The authentication role the client was 6057 authenticated for. 6059 3. "authmethod|string": The authentication method, here ""ticket"" 6061 4. "authprovider|string": The actual provider of authentication. 6062 For Ticket-based authentication, this can be freely chosen by the 6063 app, e.g. "static" or "dynamic". 6065 The "WELCOME.Details" again contain the actual authentication 6066 information active. If the authentication fails, the server will 6067 response with an "ABORT" message. 6069 14. Binary conversion of JSON Strings 6071 Binary data follows a convention for conversion to JSON strings. 6073 A *byte array* is converted to a *JSON string* as follows: 6075 1. convert the byte array to a Base64 encoded (host language) string 6077 2. prepend the string with a "\0" character 6079 3. serialize the string to a JSON string 6081 _Example_ 6083 Consider the byte array (hex representation): 6085 10e3ff9053075c526f5fc06d4fe37cdb 6087 This will get converted to Base64 6088 EOP/kFMHXFJvX8BtT+N82w== 6090 prepended with "\0" 6092 \x00EOP/kFMHXFJvX8BtT+N82w== 6094 and serialized to a JSON string 6096 "\\u0000EOP/kFMHXFJvX8BtT+N82w==" 6098 A *JSON string* is unserialized to either a *string* or a *byte 6099 array* using the following procedure: 6101 1. Unserialize a JSON string to a host language (Unicode) string 6103 2. If the string starts with a "\0" character, interpret the rest 6104 (after the first character) as Base64 and decode to a byte array 6106 3. Otherwise, return the Unicode string 6108 Below are complete Python and JavaScript code examples for conversion 6109 between byte arrays and JSON strings. 6111 14.1. Python 6113 Here is a complete example in Python showing how byte arrays are 6114 converted to and from JSON: 6116 6118 import os, base64, json, sys, binascii 6119 PY3 = sys.version_info >= (3,) 6120 if PY3: 6121 unicode = str 6123 data_in = os.urandom(16) 6124 print("In: {}".format(binascii.hexlify(data_in))) 6126 ## encoding 6127 encoded = json.dumps('\0' + base64.b64encode(data_in). 6128 decode('ascii')) 6130 print("JSON: {}".format(encoded)) 6132 ## decoding 6133 decoded = json.loads(encoded) 6134 if type(decoded) == unicode: 6135 if decoded[0] == '\0': 6136 data_out = base64.b64decode(decoded[1:]) 6137 else: 6138 data_out = decoded 6140 print("Out: {}".format(binascii.hexlify(data_out))) 6142 assert(data_out == data_in) 6144 6146 14.2. JavaScript 6148 Here is a complete example in JavaScript showing how byte arrays are 6149 converted to and from JSON: 6151 6153 var data_in = new Uint8Array(new ArrayBuffer(16)); 6155 // initialize test data 6156 for (var i = 0; i < data_in.length; ++i) { 6157 data_in[i] = i; 6158 } 6159 console.log(data_in); 6161 // convert byte array to raw string 6162 var raw_out = ''; 6163 for (var i = 0; i < data_in.length; ++i) { 6164 raw_out += String.fromCharCode(data_in[i]); 6165 } 6167 // base64 encode raw string, prepend with \0 6168 // and serialize to JSON 6169 var encoded = JSON.stringify("\0" + window.btoa(raw_out)); 6170 console.log(encoded); // "\u0000AAECAwQFBgcICQoLDA0ODw==" 6172 // unserialize from JSON 6173 var decoded = JSON.parse(encoded); 6175 var data_out; 6176 if (decoded.charCodeAt(0) === 0) { 6177 // strip first character and decode base64 to raw string 6178 var raw = window.atob(decoded.substring(1)); 6180 // convert raw string to byte array 6181 var data_out = new Uint8Array(new ArrayBuffer(raw.length)); 6182 for (var i = 0; i < raw.length; ++i) { 6183 data_out[i] = raw.charCodeAt(i); 6184 } 6185 } else { 6186 data_out = decoded; 6187 } 6189 console.log(data_out); 6191 6193 15. Security Considerations 6195 -- write me -- 6197 16. IANA Considerations 6199 TBD 6201 17. Contributors 6203 18. Acknowledgements 6205 19. References 6207 19.1. Normative References 6209 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 6210 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 6211 2003, . 6213 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 6214 Resource Identifier (URI): Generic Syntax", STD 66, RFC 6215 3986, DOI 10.17487/RFC3986, January 2005, 6216 . 6218 [RFC6455] Fette, I. and A. Melnikov, "The WebSocket Protocol", RFC 6219 6455, DOI 10.17487/RFC6455, December 2011, 6220 . 6222 19.2. Informative References 6224 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 6225 Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/ 6226 RFC2119, March 1997, 6227 . 6229 19.3. URIs 6231 [1] http://www.iana.org/assignments/websocket/websocket.xml 6233 [2] pattern-based-registration.md 6235 [3] pattern-based-registration.md 6237 [4] pattern-based-registration.md 6239 [5] http://en.wikipedia.org/wiki/PBKDF2 6241 [6] http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1 6243 [7] http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 6245 [8] http://en.wikipedia.org/wiki/Record_separator#Field_separators 6247 [9] https://github.com/oberstet/permessage-priority/blob/master/ 6248 draft-oberstein-hybi-permessage-priority.txt 6250 Authors' Addresses 6252 Tobias G. Oberstein 6253 Tavendo GmbH 6255 Email: tobias.oberstein@tavendo.de 6257 Alexander Goedde 6258 Tavendo GmbH 6260 Email: alexander.goedde@tavendo.de