Skip to content

Instantly share code, notes, and snippets.

@antonl
Created May 22, 2025 23:23
Show Gist options
  • Select an option

  • Save antonl/77946ec7f0180e554cdf50497ac6e821 to your computer and use it in GitHub Desktop.

Select an option

Save antonl/77946ec7f0180e554cdf50497ac6e821 to your computer and use it in GitHub Desktop.
Socket-based chatbot
import socket
from concurrent.futures import ThreadPoolExecutor
import logging
from datetime import datetime
# Configure logging
logging.basicConfig(
level=logging.DEBUG, # Set the minimum logging level
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', # Set the format of log messages
datefmt='%Y-%m-%d %H:%M:%S', # Set the format of the date and time
)
def handle_client(connection, address, active_connections):
log = logging.getLogger(str(address))
log.info(f"Connected {address}")
is_initialized = False
name = None
connection.send("> Welcome to the Chat Room! What's your name?\n".encode())
buf = connection.recv(1024)
if len(buf) > 0:
name = buf.decode().strip()
is_initialized = True
log.info(f"Initialized client with name {name}")
else:
log.info(f"Failed to get {name}")
while is_initialized:
# read messages
buf = connection.recv(1024)
if len(buf) > 0:
# handle broadcast
log.info(f"Received message {buf}")
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
for _address, _connection in active_connections.items():
if _address == address:
continue
log.debug(f"Sending to {_address}")
_connection.sendall(f"{timestamp} {name}: {buf.decode()}".encode())
else:
# disconnect
log.info(f"Disconnected.")
break
# cleanup
active_connections.pop(address)
def main(num_workers: int = 10):
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(('localhost', 8888))
serversocket.listen(num_workers) # become a server socket, maximum 5 connections
log = logging.getLogger("Started server")
active_connections = {}
with ThreadPoolExecutor() as pool:
try:
while True:
connection, address = serversocket.accept()
log.info(f"Connected client {address}")
active_connections[address] = connection
pool.submit(handle_client, connection=connection, address=address, active_connections=active_connections)
except KeyboardInterrupt:
return
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment