3.8 KiB
WAMP Application
Introduction
Flask-like syntaxe for WAMP projects.
This is intended to make it easier to start with autobahn/crossbar.io and abstract a lot of things : you don't have to think about the main loop, the application session class lifecycle, etc.
- It lets you react, using callback defined via decorators, to 3 things :
-
- PUB/SUB events : regular WAMP PUB/SUB events.
- RPC calls : expose a function as callable from the outside.
- app signals : internal app events allowing you to react to the app
-
lifecycle.
- Example
from autobahn.twisted.wamp import Application
from autobahn.wamp.types import PublishOptions
= Application()
app
# Register a function to allow calling it from outside
# via RPC
@app.register('a_procedure_name')
def a_procedure(arg1, arg2):
print('The procedure is called with these arguments :')
print(arg1, arg2)
# publish the event
'an_event',
app.session.publish("Some data attached to the event",
# force publisher to receive its
# own event
=PublishOptions(excludeMe=False))
options
# Register a callback that will be called when the
# event 'an_event' is triggered
@app.subscribe('an_event')
def an_event(val):
print('Received an event with something :')
print(val)
# This will be called once the application is connected
# to the server
@app.signal('onjoin')
def entry_point():
print('The application is connected !')
# Calling a_procedure()
'a_procedure_name', True, False)
app.session.call(
if __name__ == "__main__":
# By default, the application run on port 8080
print('Before the app start')
app.run()
# Now, in a Terminal:
$ python script.py
Running on 'ws://localhost:8080'
Before the app start
The application is connected !
The procedure is called with these arguments :
(True, False)
Received an event with something :
Some data attached to the event
Ok, this example is cheating a little bit because the application triggers events and listen to them, and it calls it's own code via RPC. You may want to call them from a Web page using autobahn.js (http://autobahn.ws/js/) for a more convincing demo.
If you use "yield" inside any of the callbacks, @inlineCallbacks will be applied automatically. It means every yielded line will be be added in a Deferred so they execute sequentially, in regards to the other yielded lines in the same function. In that case, you should not return, but use returnValue.
- Example
from autobahn.twisted.wamp import Application
from twisted.internet.defer import returnValue
from twisted.web.client import Agent
= Application()
app
@app.register('statuscode')
def statuscode(url):
''' Return the status code of a GET request on a URL '''
# Little hack to add asynchronous requests to our app
# It's not very clean, but for the example, it will do :)
from twisted.internet import reactor
= Agent(reactor)
agent
# Asynchronous GET request on the url
= yield agent.request('GET', url)
d
# Using returnValue and not return because the whole
# procedure is a coroutine since we used yield.
returnValue(d.code)
@app.signal('onjoin')
def entry_point():
# Calling statuscode
= "http://tavendo.com"
url = yield app.session.call('statuscode', url)
code print("GET on '%s' returned status '%s'" % (url, code))
if __name__ == "__main__":
app.run()
Now, in a Terminal:
$ python script.py
Running on 'ws://localhost:8080'
GET on 'http://tavendo.com' returned status '200'