... continued
Continues the discussion on implementing a chat server.
We'll cover the following...
The code widget below runs a simulation of the chat server with four users that message each other (including themselves) randomly.
Press + to interact
from threading import Threadfrom threading import Lockimport socket, time, randomclass ChatServer:def __init__(self, port):self.port = portself.lock = Lock()self.clients = {}def handle_client(self, client_socket):user = "unknown"while True:data = client_socket.recv(4096).decode()command, param = data.split(",")# register handlerif command == "register":print("\n{0} registered\n".format(param))with self.lock:self.clients[param] = client_socketuser = paramclient_socket.send("ack".encode())# list handlerif command == "list":with self.lock:names = self.clients.keys()names = ",".join(names)client_socket.send(names.encode())# chat handlerif command == "chat":to_socket = Nonewith self.lock:if param in self.clients:to_socket = self.clients[param]if to_socket is not None:to_socket.send(("{0} says hi\n".format(user)).encode())else:print("\nNo user by the name <{0}>\n".format(param))def run_server(self):# networking stuff to setup the connection, that the# can ignoresocket_connection = socket.socket()socket_connection.bind(('', self.port))socket_connection.listen(5)# perpetually listen for new connectionswhile True:client_socket, addr = socket_connection.accept()# spawn a thread to deal with a new client and immediately go back to# listening for new incoming connectionsThread(target=self.handle_client, args=(client_socket,), daemon=True).start()class User:def __init__(self, name, server_host, server_port):self.name = nameself.server_port = server_portself.server_host = server_hostdef receive_messages(self, server_socket):while True:print("\n{0} received: {1}\n".format(self.name, server_socket.recv(4096).decode()))def run_cleint(self):server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.connect((self.server_host, self.server_port))# register and receive ackserver_socket.send("register,{0}".format(self.name).encode())server_socket.recv(4096).decode()# wait for friends to jointime.sleep(3)# get list of friendsserver_socket.send("list,friends".encode())list_of_friends = server_socket.recv(4096).decode().split(",")num_friends = len(list_of_friends)# start listening for incoming messagesThread(target=self.receive_messages, args=(server_socket,), daemon=True).start()while True:# randomly select a friend and send a messagefriend = list_of_friends[random.randint(0, num_friends - 1)]server_socket.send("chat,{0}".format(friend).encode())time.sleep(random.randint(2, 6))if __name__ == "__main__":server_port = random.randint(10000, 65000)server_host = "127.0.0.1"server = ChatServer(server_port)# start serverThread(target=server.run_server, daemon=True).start()time.sleep(1)# jane gets onlinejane = User("Jane", server_host, server_port)Thread(target=jane.run_cleint, daemon=True).start()zak = User("Zak", server_host, server_port)Thread(target=zak.run_cleint, daemon=True).start()abhishek = User("Abhishek", server_host, server_port)Thread(target=abhishek.run_cleint, daemon=True).start()igor = User("Natasha", server_host, server_port)Thread(target=igor.run_cleint, daemon=True).start()time.sleep(30)
Note that our implementation makes generous use of daemon ...