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?"