Real-time Chat Application with Python WebSockets
This challenge tasks you with building a basic real-time chat application using Python WebSockets. You will create both a server that broadcasts messages to all connected clients and a client that can send and receive messages. This is a fundamental exercise for understanding real-time communication, essential for modern web applications like live dashboards, multiplayer games, and instant messaging.
Problem Description
You are to implement a simple multi-user chat system using Python's websockets library. The system will consist of a single server and multiple clients.
Server Requirements:
- Accept Connections: The server should be able to accept incoming WebSocket connections from multiple clients.
- Receive Messages: When a client sends a message, the server must receive it.
- Broadcast Messages: Upon receiving a message from any client, the server must broadcast that message to all currently connected clients (including the sender).
- Manage Connections: The server should keep track of all active connections. When a client disconnects, the server should be able to handle this gracefully.
- User Identification (Optional but Recommended): For clarity, you can assign a unique identifier or use the sender's address to identify who sent a message when broadcasting.
Client Requirements:
- Connect to Server: The client should be able to establish a WebSocket connection to the specified server address.
- Send Messages: The client should allow the user to input text and send it as a WebSocket message to the server.
- Receive Messages: The client must be able to receive messages broadcasted by the server and display them to the user.
- Handle Disconnection: The client should gracefully handle server disconnections.
Expected Behavior:
When multiple clients are connected to the server, and one client sends a message like "Hello everyone!", all connected clients (including the sender) should receive and display this message, perhaps prefixed with the sender's identifier (e.g., Client_127.0.0.1:port: Hello everyone!).
Edge Cases to Consider:
- Simultaneous Messages: What happens if multiple clients send messages at almost the same time?
- Client Disconnects Unexpectedly: How does the server handle a client closing its connection abruptly?
- Server Shutdown: How should clients react if the server shuts down?
Examples
Example 1: Basic Interaction
- Scenario: Two clients connect to the server. Client A sends "Hi!". Client B sends "Hello A!".
- Server Output (Internal Log/Debug):
New connection from 127.0.0.1:5000 Received message from 127.0.0.1:5000: "Hi!" Broadcasting to all clients: Client_127.0.0.1:5000: Hi! New connection from 127.0.0.1:5001 Received message from 127.0.0.1:5001: "Hello A!" Broadcasting to all clients: Client_127.0.0.1:5001: Hello A! - Client A Output:
Connected to ws://127.0.0.1:8765 Received: Client_127.0.0.1:5001: Hello A! Received: Client_127.0.0.1:5000: Hi! - Client B Output:
Connected to ws://127.0.0.1:8765 Received: Client_127.0.0.1:5000: Hi! Received: Client_127.0.0.1:5001: Hello A! - Explanation: Client A sends "Hi!". The server receives it and broadcasts it to all connected clients, including Client A and Client B. Then, Client B sends "Hello A!". The server broadcasts this to all, and both clients display it.
Example 2: Client Disconnection
- Scenario: Three clients (A, B, C) are connected. Client B disconnects. Client A then sends "Where did B go?".
- Server Output (Internal Log/Debug):
... (previous connections and messages) ... Client 127.0.0.1:5001 disconnected Received message from 127.0.0.1:5000: "Where did B go?" Broadcasting to all clients: Client_127.0.0.1:5000: Where did B go? - Client A Output:
... Received: Client_127.0.0.1:5001: Hello A! (from previous step) Received: Client_127.0.0.1:5000: Where did B go? - Client C Output:
... Received: Client_127.0.0.1:5001: Hello A! (from previous step) Received: Client_127.0.0.1:5000: Where did B go? - Explanation: The server detects Client B's disconnection and removes it from its active connections. When Client A sends a message, it's broadcasted only to the remaining connected clients (A and C).
Constraints
- The server should listen on
ws://127.0.0.1:8765. - Clients should connect to
ws://127.0.0.1:8765. - Your implementation should use the
websocketsPython library. - The application should handle at least 10 concurrent clients without significant lag.
- Messages are expected to be UTF-8 encoded strings.
Notes
- You will need to install the
websocketslibrary:pip install websockets. - For the server, consider using
asynciofor handling concurrent connections. - For the client, you can use a loop to continuously read user input and send it, while also having a separate task to receive messages from the server.
- Think about how to store and manage the set of connected clients on the server.
- You might want to include a simple way to start and stop the server and clients for testing purposes.
- The
websocketslibrary provides methods likeconnect,recv, andsendfor clients, andserve,websocket.recv, andwebsocket.sendfor servers. - Consider adding a simple mechanism to identify clients, perhaps by their
websocket.remote_address.