diff --git a/examples/websocket/mini_ticker.py b/examples/websocket/mini_ticker.py index d991978..46234bf 100644 --- a/examples/websocket/mini_ticker.py +++ b/examples/websocket/mini_ticker.py @@ -1,23 +1,70 @@ -import time +import asyncio import logging +import time +from typing import Dict, Any + from aster.lib.utils import config_logging from aster.websocket.client.stream import WebsocketClient as Client +# Set up logging for the client application config_logging(logging, logging.DEBUG) +logger = logging.getLogger(__name__) + +# --- Handlers --- + +def message_handler(message: Dict[str, Any]) -> None: + """ + Handles incoming messages from the WebSocket stream. + + Args: + message: The parsed message payload (usually JSON). + """ + logger.info(f"Received message: {message}") -def message_handler(message): - print(message) +# --- Main Application Logic --- -my_client = Client() -my_client.start() +async def main_async(): + """ + Asynchronously runs the WebSocket client, subscribes to a stream, + and keeps the connection alive for a set duration. + """ + client = Client() + + try: + logger.debug("Starting WebSocket client...") + # Start the client (likely runs in a separate thread/task internally) + client.start() -my_client.mini_ticker( - id=1, - callback=message_handler, - symbol="btcusdt" -) + # Subscribe to a stream + logger.info("Subscribing to mini_ticker stream for BTCUSDT...") + client.mini_ticker( + id=1, + callback=message_handler, + symbol="btcusdt" + ) -time.sleep(2) + # Keep the main coroutine alive to allow the client thread/task to run + # Use asyncio.sleep for non-blocking wait instead of time.sleep + logger.info("Waiting for 10 seconds of streaming data...") + await asyncio.sleep(10) + + except Exception as e: + logger.error(f"An error occurred during client execution: {e}", exc_info=True) + + finally: + # Ensure the client connection is closed cleanly, regardless of errors + logger.debug("Closing WebSocket connection.") + client.stop() + logger.info("Client stopped successfully.") -logging.debug("closing ws connection") -my_client.stop() +if __name__ == "__main__": + # The client runs synchronously if not wrapped, but using asyncio.run + # provides a cleaner execution context, especially for cleanup. + try: + asyncio.run(main_async()) + except KeyboardInterrupt: + logger.warning("Program interrupted by user.") + except RuntimeError as e: + # Handle the common RuntimeError when asyncio tries to close the loop + if "Event loop is closed" not in str(e): + raise