|
|
- #!/usr/bin/env python3.7
- import socket # socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
- import logging
- import threading
- import ClientConnection
-
-
- class Server(object):
- """
- A simple chat application server
- """
- clients = []
-
- soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- def __init__(self, host: str, port: int, maxClients=64):
- self.host = host
- self.port = port
- self.soc.bind((host, port))
- self.maxClients = maxClients
-
- def run(self) -> None:
- """
- Start the server and start to listen for incoming connection
- """
- self.soc.listen(self.maxClients)
- logging.info('Start listening on {}:{} maximum {} clients'.format(
- self.host, self.port, self.maxClients))
- while True:
- conn, addr = self.soc.accept()
- client = ClientConnection.ClientConnection(self, conn, addr)
- msg = '{} has joined the chat.'.format(client.addr)
- self._announce(msg)
- self.clients.append(client)
- t = threading.Thread(target=client.serve)
- t.daemon = True
- t.start()
-
- def removeClient(self, client: ClientConnection.ClientConnection) -> None:
- """
- Remove client from this server list of connected clients
- """
- msg = '{} has left the chat.'.format(client.nameFormat())
- self.clients.remove(client)
- self._announce(msg)
-
- def _announce(self, announcement: str) -> None:
- """
- Send announcement from system to all connected clients
- """
- msg = '[system] {}'.format(announcement)
- logging.info(msg)
- for client in self.clients:
- client.send(msg)
-
- def sendToAll(self, sender: ClientConnection.ClientConnection, msg: str) -> None:
- """
- Broadcast message from one client to other clients
- """
- msg = '{} {}'.format(sender.nameFormat(), msg)
- logging.info(msg)
- for client in self.clients:
- if client != sender:
- client.send(msg)
|