简体   繁体   中英

Urwid, autobahn and twisted eventloop integration

i'm using autobahn to connect to a server and get "push" notifications, and i want to make a simple urwid interface using their twisted event loop. However I am not sure what the best way is to set the urwid text from my autobahn handler class. In the following code you can see my current implementation where i want to call the "updateText" method from inside my "MyFrontendComponent" class. What is the best way of doing this?

import urwid
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks
from twisted.internet.endpoints import clientFromString

from autobahn.twisted import wamp, websocket
from autobahn.wamp import types
from autobahn.wamp.serializer import *


class MyFrontendComponent( wamp.ApplicationSession, object):
    @inlineCallbacks
    def onJoin(self, details):
        ## call a remote procedure
        try:
            now = yield self.call(u'com.timeservice.now')
        except Exception as e:
            print("Error: {}".format(e))
        else:
            print("Current time from time service: {}".format(now))

        ## subscribe to a topic
        self.received = 0

        def on_event(i):
            print("Got event: {}".format(i))
            self.received += 1
            if self.received > 5:
                self.leave()

        sub = yield self.subscribe(on_event, u'com.myapp.topic1')
        print("Subscribed with subscription ID {}".format(sub.id))

    def onDisconnect(self):
        reactor.stop()

class MyApp(object):
    txt = urwid.Text(u"Hello World")
    def __init__(self):
        component_config = types.ComponentConfig(realm="realm1")
        session_factory = wamp.ApplicationSessionFactory(config=component_config)
        session_factory.session = MyFrontendComponent
        serializers = None
        serializers = []
        serializers.append(JsonSerializer())
        transport_factory = websocket.WampWebSocketClientFactory(session_factory,
                                                             serializers=serializers, debug=False, debug_wamp=False)
        client = clientFromString(reactor, "tcp:127.0.0.1:8080")
        client.connect(transport_factory)
        fill = urwid.Filler(self.txt, 'top')
        loop = urwid.MainLoop(fill, unhandled_input=self.show_or_exit, event_loop=urwid.TwistedEventLoop())
        loop.run()

    def updateText(self, input):
        self.txt.set_text(input)

    def show_or_exit(self, key):
        if key in ('q', 'Q'):
            raise urwid.ExitMainLoop()
        self.txt.set_text(repr(key))

if __name__ == '__main__':
    MyApp()

And the server code:

import sys
import six
import datetime
from twisted.python import log
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks
from twisted.internet.endpoints import serverFromString
from autobahn.wamp import types
from autobahn.twisted.util import sleep
from autobahn.twisted import wamp, websocket

class MyBackendComponent(wamp.ApplicationSession):
    @inlineCallbacks
    def onJoin(self, details):
        ## register a procedure for remote calling
        def utcnow():
            print("Someone is calling me;)")
            now = datetime.datetime.utcnow()
            return six.u(now.strftime("%Y-%m-%dT%H:%M:%SZ"))

        reg = yield self.register(utcnow, u'com.timeservice.now')
        print("Registered procedure with ID {}".format(reg.id))

        ## publish events to a topic
        counter = 0
        while True:
            self.publish(u'com.myapp.topic1', counter)
            print("Published event.")
            counter += 1
            yield sleep(1)

if __name__ == '__main__':
    ## 0) start logging to console
    log.startLogging(sys.stdout)
    ## 1) create a WAMP router factory
    router_factory = wamp.RouterFactory()
    ## 2) create a WAMP router session factory
    session_factory = wamp.RouterSessionFactory(router_factory)
    ## 3) Optionally, add embedded WAMP application sessions to the router
    component_config = types.ComponentConfig(realm="realm1")
    component_session = MyBackendComponent(component_config)
    session_factory.add(component_session)
    ## 4) create a WAMP-over-WebSocket transport server factory
    transport_factory = websocket.WampWebSocketServerFactory(session_factory,
                                                             debug=False,
                                                             debug_wamp=False)
    ## 5) start the server from a Twisted endpoint
    server = serverFromString(reactor, "tcp:8080")
    server.listen(transport_factory)
    ## 6) now enter the Twisted reactor loop
    reactor.run()

Thanks!

Since I don't have enough rep to reply in the comment I will do it here! The answer tips given in the comment by oberstet helped me to do this properly without any global variables! :)

Thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM