Archived
1
0
Fork 0
This repository has been archived on 2024-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
PyTchat/server.py

121 lines
4 KiB
Python
Raw Normal View History

from threading import Thread, RLock
2019-07-15 22:42:53 +02:00
from SecureSocketService import Socket
from socket import error as socket_error
2019-07-15 22:42:53 +02:00
class Server(Socket):
def __init__(self, host: str = "localhost", port: int = 3621, service_id: int = 2):
print("Server start")
2019-07-15 22:42:53 +02:00
super().__init__()
self.socket.bind((host, port))
self.socket.listen(5)
self.service_id = service_id
self.command_suffix = "/"
2019-07-19 18:36:45 +02:00
self.welcome_msg = "Welcome ! Type \"/help\" to see commands and \"quit\" to exit"
self.commands = {"help": self.command_help, "players list": self.command_players_list}
2019-07-15 22:42:53 +02:00
self.clients = dict()
self.clients_lock = RLock()
print("Wait for connexion...")
2019-07-15 22:42:53 +02:00
Thread(target=self.connexion).start()
def connexion(self):
while True:
try:
c, address = self.connect_client(self.socket)
except (socket_error, ConnectionError):
continue
else:
name = self.client_name(c)
if name:
with self.clients_lock:
self.clients[name] = c
self.send(c, self.welcome_msg)
self.broadcast(f"{name} is online !")
Thread(target=self.listen_client, args=(name,)).start()
2019-07-15 22:42:53 +02:00
def client_name(self, sock):
while True:
try:
self.send(sock, "Your name ?")
name = self.receive(sock)
with self.clients_lock:
if name in self.clients:
self.send(sock, "Name already taken !")
elif name.lower() == "quit":
sock.close()
name = None
else:
break
except socket_error:
2019-07-15 22:42:53 +02:00
name = None
break
return name
def listen_client(self, name):
while True:
try:
data = self.receive(self.clients[name])
if data.lower() == "quit":
raise ConnectionError("Client quit")
except (socket_error, ConnectionError):
self.client_quit(name)
2019-07-15 22:42:53 +02:00
break
else:
if not self.command(data, name):
Thread(target=self.broadcast, args=(f"{name}: {data}",)).start()
2019-07-15 22:42:53 +02:00
def broadcast(self, message):
2019-07-15 22:42:53 +02:00
print(message)
with self.clients_lock:
for i in self.clients:
try:
self.send(self.clients[i], message)
except socket_error:
continue
def client_quit(self, name):
with self.clients_lock:
try:
self.send(self.clients[name], "quit")
self.clients[name].close()
except socket_error:
pass
finally:
del self.clients[name]
self.broadcast(f"{name} is offline !")
def command(self, command, author):
command = command.lower()
if (command[:1] == self.command_suffix) and (command[1:] in self.commands):
command = command[1:]
elif command[:1] == self.command_suffix:
command = "help"
else:
return False
try:
print(f"{author} use command {command}")
self.commands[command](author)
except socket_error:
self.client_quit(author)
finally:
return True
def command_help(self, author):
message = "[Help]"
for i in self.commands:
message += "\n- " + i
with self.clients_lock:
self.send(self.clients[author], message)
def command_players_list(self, author):
with self.clients_lock:
message = f"[Players list | {len(self.clients)} online]"
for i in self.clients:
message += "\n- " + i
self.send(self.clients[author], message)
2019-07-15 22:42:53 +02:00
if __name__ == "__main__":
Server()