projet-reseau-1/shared/server/__init__.py

125 lines
4.0 KiB
Python

import asyncio
import logging
import socket
from .game import ConcurrentData, TableAlreadyExistException
from .message import parse_message, BiCommand
class Server:
def __init__(self) -> None:
self.__data = ConcurrentData()
async def handle_client(self, client: socket.socket) -> None:
loop = asyncio.get_event_loop()
logging.info("New client connected")
await loop.sock_sendall(client, b"HELLO\r\n")
try:
request = parse_message((await loop.sock_recv(client, 4096)).decode('utf8'))
except BrokenPipeError:
return
if len(request) != 2:
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
client.close()
return
if request[0] == BiCommand.NAME:
name = request[1]
else:
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
client.close()
return
if not await self.__data.has_table(name):
await loop.sock_sendall(client, b"ERROR: NO SUCH TABLE\r\nEND\r\n")
client.close()
return
table = await self.__data.get_table(name)
if await table.add_client(client, self.__data):
await loop.sock_sendall(client, b"OK\r\n")
else:
await loop.sock_sendall(client, b"ERROR: ROOM FULL\r\nEND\r\n")
client.close()
async def handle_croupier(self, client: socket.socket) -> None:
logging.debug("New croupier connected")
loop = asyncio.get_event_loop()
await loop.sock_sendall(client, b"HELLO\r\n")
try:
request = parse_message((await loop.sock_recv(client, 4096)).decode('utf8'))
except BrokenPipeError:
return
if len(request) != 2:
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
client.close()
return
if request[0] == BiCommand.NAME:
name = request[1]
await loop.sock_sendall(client, b"OK\r\n")
else:
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
client.close()
return
try:
request = parse_message((await loop.sock_recv(client, 4096)).decode('utf8'))
except BrokenPipeError:
return
if len(request) != 2:
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
client.close()
return
if request[0] == BiCommand.TIME:
time = request[1]
try:
await self.__data.add_table(name, int(time))
await loop.sock_sendall(client, b"OK\r\n")
except TableAlreadyExistException:
await loop.sock_sendall(client, b"ERROR: TABLE ALREADY EXIST\r\nEND\r\n")
else:
await loop.sock_sendall(client, b"ERROR: INVALID COMMAND\r\nEND\r\n")
client.close()
async def listen_client(self) -> None:
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.bind(('0.0.0.0', 667))
listen_socket.listen(8)
listen_socket.setblocking(False)
loop = asyncio.get_event_loop()
while True:
client, _ = await loop.sock_accept(listen_socket)
loop.create_task(self.handle_client(client))
async def listen_croupier(self) -> None:
server_croupier = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_croupier.bind(('0.0.0.0', 668))
server_croupier.listen(8)
server_croupier.setblocking(False)
loop = asyncio.get_event_loop()
while True:
client, _ = await loop.sock_accept(server_croupier)
loop.create_task(self.handle_croupier(client))
async def run(self):
loop = asyncio.get_event_loop()
loop_client = loop.create_task(self.listen_client())
loop_croupier = loop.create_task(self.listen_croupier())
logging.info("Running server ...")
await asyncio.gather(loop_client, loop_croupier)