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!"
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.
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.
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.
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.
How to write async programs?
async
await
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With