rewrote serverside netcode to support multiple connections at once

This commit is contained in:
steev 2024-01-04 02:49:43 +01:00
parent b679716fe1
commit e5e42aa6d9
2 changed files with 76 additions and 60 deletions

View File

@ -2,7 +2,7 @@ import json
import socket import socket
import threading import threading
from Classes.System.Network.Handler.EventHandler import UDPEventHandler, TCPEventHandler from Classes.System.Network.EventHandler import UDPEventHandler, TCPEventHandler
class NetworkManager: class NetworkManager:
@ -11,88 +11,104 @@ class NetworkManager:
__Port:str __Port:str
__BufferSize:int = 1024 __BufferSize:int = 1024
__udpSocket:socket __udpSocket:socket
__users:list
__UDPClientThread:threading.Thread __UDPClientThread:threading.Thread
__eventHandler: UDPEventHandler __eventHandler: UDPEventHandler
def __init__(self, Addr:str, Port:str): def __init__(self, Addr:str, Port:str):
clientUdpSocket, clientUdpAddress = self.__udpSocket.accept() clientUdpSocket, clientUdpAddress = self.__udpSocket.accept()
self.__Addr = Addr self.__Addr = Addr
self.__Port = Port self.__Port = int(Port)
self.__users = {}
self.__udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.__udpSocket.bind((self.__Addr, self.__Port))
self.__eventHandler = UDPEventHandler(clientUdpSocket) self.__eventHandler = UDPEventHandler(clientUdpSocket)
self.__UDPClientThread = threading.Thread(target=self.handleUDPConnection, args=(clientUdpSocket, clientUdpAddress))
self.__UDPClientThread = threading.Thread(target=self.receive)
self.__UDPClientThread.start() self.__UDPClientThread.start()
# handles ticking the game loop server side converting data and passing of to the event handler # handles incomming udp data
def handleUDPConnection(self, socket:socket, address): def receive(self):
# states that a connection has been established
print(f"Connected with {address}")
# Communication with client
while True: while True:
data = socket.recv(self.__bufferSize) data, address = self.__udpSocket.recvfrom(self.__BufferSize)
if not data:
break
# decode message for handling
message = data.decode() message = data.decode()
messageJson = json.loads(message) messageJson = json.loads(message)
user = messageJson.get("user")
if messageJson["user"] in self.__users: if user not in self.__users:
self.__users[user] = address # Storing new user in dictionary
# Process the message and handle accordingly
self.__eventHandler.handleUDPEvents(messageJson) self.__eventHandler.handleUDPEvents(messageJson)
else: print(f"Received message from {address}: {message}")
break
print(f"received message from {address}: {message}") def broadcast(self, payload:dict):
for user_address in self.__users.values():
self.__udpSocket.sendto(json.dumps(payload).encode(), user_address)
def send(self, payload:dict, user:str):
if user in self.__users:
def send(payload:bytes): self.__udpSocket.sendto(json.dumps(payload).encode(), self.__users[user])
# todo: lookup how to send data
pass
class TCP: class TCP:
__Addr:str
__Port:str
__BufferSize:int = 1024
__tcpSocket:socket
__TCPClientThread:threading.Thread
__eventHandler:TCPEventHandler
def __init__(self, Addr: str, Port: str): def __init__(self, Addr: str, Port: str):
clientTcpSocket, clientTcpAddress = self.__tcpSocket.accept()
self.__Addr = Addr self.__Addr = Addr
self.__Port = Port self.__Port = int(Port)
self.__eventHandler = TCPEventHandler(clientTcpSocket) self.__users = {}
self.__TCPClientThread = threading.Thread(target=self.handleTCPConnection, args=(clientTcpSocket, clientTcpAddress)) self.__tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__TCPClientThread.start() self.__tcpSocket.bind((self.__Addr, self.__Port))
self.__tcpSocket.listen()
# handles ticking the game loop server side converting data and passing of to the event handler self.__eventHandler = TCPEventHandler()
def handleTCPConnection(self, socket:socket, address):
# states that a connection has been established
print(f"Connected with {address}")
# Communication with client self.__receive_thread = threading.Thread(target=self.accept_connections)
self.__receive_thread.start()
def accept_connections(self):
while True: while True:
data = socket.recv(1024) client_tcp_socket, client_address = self.__tcpSocket.accept()
print(f"Connected with {client_address}")
self.__users[client_address] = client_tcp_socket
client_handler_thread = threading.Thread(target=self.receive, args=(client_tcp_socket, client_address))
client_handler_thread.start()
def receive(self, __tcpSocket: socket.socket, address):
while True:
try:
data = __tcpSocket.recv(1024)
if not data: if not data:
break break
# decode message for handling
message = data.decode() message = data.decode()
messageJson = json.loads(message) message_json = json.loads(message)
user = message_json.get("user")
if messageJson["user"] in self.__users: if user not in self.__users:
self.__eventHandler.handleTCPEvents(messageJson) self.__users[user] = address # Storing new user in dictionary
else:
# Process the message and handle accordingly
self.__eventHandler.handleTCPEvents(message_json)
print(f"Received message from {address}: {message}")
except ConnectionResetError:
print(f"Connection with {address} closed.")
del self.__users[address]
break break
print(f"received message from {address}: {message}") def broadcast(self, payload: dict):
for user_socket in self.__users.values():
user_socket.send(json.dumps(payload).encode())
def send(self, payload: dict, user_address):
if user_address in self.__users:
user_socket = self.__users[user_address]
user_socket.send(json.dumps(payload).encode())
else:
print(f"User {user_address} is not connected.")
def close(self):
def send(payload:bytes): self.__tcpSocket.close()
# todo: lookup how to send data
pass
tcp: TCP tcp: TCP
udp: UDP udp: UDP

View File

@ -2,7 +2,7 @@ import json
import socket import socket
import threading import threading
from Classes.System.Network.Handler.EventHandler import TCPEventHandler, UDPEventHandler from Game_Client.Classes.System.Network.EventHandler import TCPEventHandler, UDPEventHandler
class NetworkManager: class NetworkManager:
class UDP: class UDP: