async def run_client( uri: str, loop: asyncio.AbstractEventLoop, inputs: asyncio.Queue[str], stop: asyncio.Future[None], ) -> None: try: websocket = await websockets.connect(uri) except Exception as exc: print_over_input(f"Failed to connect to {uri}: {exc}.") exit_from_event_loop_thread(loop, stop) return else: print_during_input(f"Connected to {uri}.") try: while True: incoming: asyncio.Future[Any] = asyncio.ensure_future( websocket.recv()) outgoing: asyncio.Future[Any] = asyncio.ensure_future(inputs.get()) done: Set[asyncio.Future[Any]] pending: Set[asyncio.Future[Any]] done, pending = await asyncio.wait( [incoming, outgoing, stop], return_when=asyncio.FIRST_COMPLETED) # Cancel pending tasks to avoid leaking them. if incoming in pending: incoming.cancel() if outgoing in pending: outgoing.cancel() if incoming in done: try: message = incoming.result() except websockets.ConnectionClosed: break else: if isinstance(message, str): print_during_input("< " + message) else: print_during_input("< (binary) " + message.hex()) if outgoing in done: message = outgoing.result() await websocket.send(message) if stop in done: break finally: await websocket.close() close_status = format_close(websocket.close_code, websocket.close_reason) print_over_input(f"Connection closed: {close_status}.") exit_from_event_loop_thread(loop, stop)
def run_client(uri, loop, inputs, stop): try: websocket = yield from websockets.connect(uri) except Exception as exc: print_over_input("Failed to connect to {}: {}.".format(uri, exc)) exit_from_event_loop_thread(loop, stop) return else: print_during_input("Connected to {}.".format(uri)) try: while True: incoming = asyncio_ensure_future(websocket.recv()) outgoing = asyncio_ensure_future(inputs.get()) done, pending = yield from asyncio.wait( [incoming, outgoing, stop], return_when=asyncio.FIRST_COMPLETED, ) # Cancel pending tasks to avoid leaking them. if incoming in pending: incoming.cancel() if outgoing in pending: outgoing.cancel() if incoming in done: try: message = incoming.result() except websockets.ConnectionClosed: break else: print_during_input('< ' + message) if outgoing in done: message = outgoing.result() yield from websocket.send(message) if stop in done: break finally: yield from websocket.close() close_status = format_close( websocket.close_code, websocket.close_reason) print_over_input( "Connection closed: {close_status}." .format(close_status=close_status) ) exit_from_event_loop_thread(loop, stop)
async def close(self): ws = self._ws self._ws = None await ws.close() close_status = exceptions.format_close(ws.close_code, ws.close_reason) logger.info(f"Connection closed: {close_status}.")