Ping-Pong: Basic Event Loop =========================== The simplest event-based example. Alice sends a sequence of messages to Bob, who replies to each one. No state machine — just a simple if/else to choose the reply. Found in ``examples/event-based/pingPong/``. This is purely classical (no quantum operations). It demonstrates the basic async event loop pattern before adding state machines and quantum in later examples. Alice (client) -------------- Alice sends a list of messages and prints Bob's replies:: async def run_alice(reader: StreamReader, writer: StreamWriter): messages = ["ping", "ping", "hello", "ping"] for msg in messages: print(f"Alice: sending '{msg}'") writer.write(msg.encode("utf-8")) await writer.drain() reply_data = await reader.read(255) reply = reply_data.decode("utf-8") print(f"Alice: received '{reply}'") Bob (server) ------------ Bob replies "pong" to "ping" and "no way!" to anything else:: async def run_bob(reader: StreamReader, writer: StreamWriter): while True: data = await reader.read(255) if not data: break # Alice disconnected message = data.decode("utf-8") if message == "ping": reply = "pong" else: reply = "no way!" writer.write(reply.encode("utf-8")) await writer.drain() Key concepts ------------ - **reader/writer**: The async streams for classical TCP communication. ``writer.write()`` sends bytes, ``await reader.read(N)`` receives up to N bytes. - **await writer.drain()**: Ensures the write buffer is flushed to the network. - **Connection lifecycle**: Bob's loop exits when ``reader.read()`` returns empty bytes, meaning Alice has disconnected. Running ------- :: cd examples/event-based/pingPong bash run.sh Expected output:: Alice: sending 'ping' Bob: received 'ping' Bob: sending 'pong' Alice: received 'pong' Alice: sending 'ping' ... Alice: sending 'hello' Bob: received 'hello' Bob: sending 'no way!' Alice: received 'no way!'