Search code examples
pythondjangotwistedautobahncrossbar

Crossbar.io: How to publish a message on a topic using a Django service?


I just started using Crossbar.io to implement a live stats page. I've looked at a lot of code examples, but I can't figure out how to do this:

I have a Django service (to avoid confusion, you can assume I´m talking about a function in views.py) and I'd like it to publish messages in a specific topic, whenever it gets called. I've seen these approaches: (1) Extending ApplicationSession and (2) using an Application instance that is "runned".

None of them work for me, because the Django service doesn't live inside a class, and is not executed as a stand-alone python file either, so I don't find a way to call the "publish" method (that is the only thing I want to do on the server side).

I tried to get an instance of "StatsBackend", which extends ApplicationSession, and publish something... But StatsBackend._instance is None always (even when I execute 'crossbar start' and StatsBackend.init() is called).

StatsBackend.py:

from twisted.internet.defer import inlineCallbacks
from autobahn import wamp
from autobahn.twisted.wamp import ApplicationSession

class StatsBackend(ApplicationSession):

    _instance = None

    def __init__(self, config):
        ApplicationSession.__init__(self, config)
        StatsBackend._instance = self

    @classmethod
    def update_stats(cls, amount):
        if cls._instance:
            cls._instance.publish('com.xxx.statsupdate', {'amount': amount})

    @inlineCallbacks
    def onJoin(self, details):
        res = yield self.register(self)
        print("CampaignStatsBackend: {} procedures registered!".format(len(res)))

test.py:

import StatsBackend

StatsBackend.update_stats(100) #Doesn't do anything, StatsBackend._instance is None

Solution

  • Django is a blocking WSGI application, and that does not blend well with AutobahnPython, which is non-blocking (runs on top of Twisted or asyncio).

    However, Crossbar.io has a built-in REST bridge, which includes a HTTP Pusher to which you can submit events via any HTTP/POST capable client. Crossbar.io will forward those events to regular WAMP subscribers (eg via WebSocket in real-time).

    Crossbar.io also comes with a complete application template to demonstrate above functionality. To try:

    cd ~/test1
    crossbar init --template pusher
    crossbar start
    

    Open your browser at http://localhost:8080 (open the JS console) and in a second terminal

    curl -H "Content-Type: application/json" \
       -d '{"topic": "com.myapp.topic1", "args": ["Hello, world"]}' \
       http://127.0.0.1:8080/push
    

    You can then do the publish from within a blocking application like Django.