Skip to content Skip to sidebar Skip to footer

How Can I Implement An Interactive Websocket Client With Autobahn Asyncio?

I'm trying to implement a websocket/wamp client using autobahn|python and asyncio, and while it's somewhat working, there are parts that have eluded me. What I'm really trying to d

Solution 1:

You can listen on a socket asynchronous inside the event loop, using loop.sock_accept. You can just call a coroutine to setup the socket inside of onConnect or onJoin:

try:
    import asyncio
except ImportError:
    ## Trollius >= 0.3 was renamedimport trollius as asyncio

from autobahn.asyncio import wamp, websocket
import socket

classMyFrontendComponent(wamp.ApplicationSession):
    defonConnect(self):
        self.join(u"realm1")

    @asyncio.coroutinedefsetup_socket(self):
        # Create a non-blocking socket
        self.sock = socket.socket()
        self.sock.setblocking(0)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind(('localhost', 8889))
        self.sock.listen(5)
        loop = asyncio.get_event_loop()
        # Wait for connections to come in. When one arrives,# call the time service and disconnect immediately.whileTrue:
            conn, address = yieldfrom loop.sock_accept(self.sock)
            yieldfrom self.call_timeservice()
            conn.close()

    @asyncio.coroutinedefonJoin(self, details):
        print('joined')
        # Setup our socket server
        asyncio.async(self.setup_socket())

        ## call a remote procedure##yieldfrom self.call_timeservice()

    @asyncio.coroutinedefcall_timeservice(self):
        try:
           now = yieldfrom self.call(u'com.timeservice.now')
        except Exception as e:
           print("Error: {}".format(e))
        else:
           print("Current time from time service: {}".format(now))

    ... # The rest is the same

Solution 2:

Thanks for the response dano. Not quite the solution I needed but it pointed me in the right direction. Yes, I wish to have the client mae remote RPC calls from an external trigger.

I came up with the following which allows me to pass a string for the specific call ( though only one is implemented right now)

Here's what I came up with, though I'm not sure how elegant it is.

import asyncio
from autobahn.asyncio import wamp, websocket
import threading
import time
import socket


rsock, wsock = socket.socketpair()

classMyFrontendComponent(wamp.ApplicationSession):
    defonConnect(self):
        self.join(u"realm1")

    @asyncio.coroutinedefsetup_socket(self):
        # Create a non-blocking socket
        self.sock = rsock
        self.sock.setblocking(0)
        loop = asyncio.get_event_loop()
        # Wait for connections to come in. When one arrives,# call the time service and disconnect immediately.whileTrue:
            rcmd = yieldfrom loop.sock_recv(rsock,80)
            yieldfrom self.call_service(rcmd.decode())

    @asyncio.coroutinedefonJoin(self, details):
        # Setup our socket server
        asyncio.async(self.setup_socket())


    @asyncio.coroutinedefcall_service(self,rcmd):
        print(rcmd)
        try:
           now = yieldfrom self.call(rcmd)
        except Exception as e:
           print("Error: {}".format(e))
        else:
           print("Current time from time service: {}".format(now))



    defonLeave(self, details):
        self.disconnect()

    defonDisconnect(self):
        asyncio.get_event_loop().stop()



defstart_aloop() :
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    transport_factory = websocket.WampWebSocketClientFactory(session_factory,
                    debug = False,
                    debug_wamp = False)
    coro = loop.create_connection(transport_factory, '127.0.0.1', 8080)
    loop.run_until_complete(coro)
    loop.run_forever()
    loop.close()

if __name__ == '__main__':
    session_factory = wamp.ApplicationSessionFactory()
    session_factory.session = MyFrontendComponent

    ## 4) now enter the asyncio event loopprint('starting thread')
    thread = threading.Thread(target=start_aloop)
    thread.start()
    time.sleep(5)
    wsock.send(b'com.timeservice.now')
    time.sleep(5)
    wsock.send(b'com.timeservice.now')
    time.sleep(5)
    wsock.send(b'com.timeservice.now')

Post a Comment for "How Can I Implement An Interactive Websocket Client With Autobahn Asyncio?"