Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I implement asyncio websockets in a class?

Tags:

I would like to connect to a websocket via asyncio and websockets, with a format as shown below. How would I be able to accomplish this?

from websockets import connect   class EchoWebsocket:      def __init__(self):         self.websocket = self._connect()      def _connect(self):         return connect("wss://echo.websocket.org")      def send(self, message):         self.websocket.send(message)      def receive(self):         return self.websocket.recv()  echo = EchoWebsocket() echo.send("Hello!") print(echo.receive())  # "Hello!" 
like image 811
2Cubed Avatar asked May 22 '16 02:05

2Cubed


People also ask

How do you implement WebSockets?

webSockets are implemented as follows: Client makes HTTP request to server with "upgrade" header on the request. If server agrees to the upgrade, then client and server exchange some security credentials and the protocol on the existing TCP socket is switched from HTTP to webSocket.

How do you create a WebSocket in Python?

WebSocket Client with PythonCreate a new File “client.py” and import the packages as we did in our server code. Now let's create a Python asynchronous function (also called coroutine). async def test(): We will use the connect function from the WebSockets module to build a WebSocket client connection.

How do I install a WebSocket in Python?

Type “ pip install websocket-client ” (without quotes), hit Enter. If it doesn't work, try "pip3 install websocket-client" or “ python -m pip install websocket-client “. Wait for the installation to terminate successfully.

How do WebSockets work internally?

WebSocket uses HTTP as the initial transport mechanism, but keeps the TCP connection alive after the HTTP response is received so that it can be used for sending messages between client and server. WebSockets allow us to build “real-time” applications without the use of long-polling.


1 Answers

How to write async programs?

  1. You should define async funcs with async
  2. You should call async funcs with await
  3. You need event loop to start your async program

All other is almost same as with regular Python programs.

import asyncio from websockets import connect   class EchoWebsocket:     async def __aenter__(self):         self._conn = connect("wss://echo.websocket.org")         self.websocket = await self._conn.__aenter__()                 return self      async def __aexit__(self, *args, **kwargs):         await self._conn.__aexit__(*args, **kwargs)      async def send(self, message):         await self.websocket.send(message)      async def receive(self):         return await self.websocket.recv()   async def main():     async with EchoWebsocket() as echo:         await echo.send("Hello!")         print(await echo.receive())  # "Hello!"   if __name__ == '__main__':     loop = asyncio.get_event_loop()     loop.run_until_complete(main()) 

Output:

Hello! 

As you see, code is almost same as you wrote.

Only difference is that websockets.connect designed to be async context manager (it uses __aenter__, __aexit__). It's necessary to release connection and will also help you to make async operations during class initialization (since we have no async version of __init__).

I advise you to organize your class same way. But if you really don't want to use context manager for some reason you can use new __await__ method to make async initialization and some other async function to release connection:

import sys import asyncio from websockets import connect   class EchoWebsocket:     def __await__(self):         # see: http://stackoverflow.com/a/33420721/1113207         return self._async_init().__await__()      async def _async_init(self):         self._conn = connect("wss://echo.websocket.org")         self.websocket = await self._conn.__aenter__()         return self      async def close(self):         await self._conn.__aexit__(*sys.exc_info())      async def send(self, message):         await self.websocket.send(message)      async def receive(self):         return await self.websocket.recv()   async def main():     echo = await EchoWebsocket()     try:         await echo.send("Hello!")         print(await echo.receive())  # "Hello!"     finally:         await echo.close()   if __name__ == '__main__':     loop = asyncio.get_event_loop()     loop.run_until_complete(main()) 

Many examples of using websockets you can find in it's docs.

like image 160
Mikhail Gerasimov Avatar answered Oct 11 '22 04:10

Mikhail Gerasimov