Skip to content

Commit

Permalink
[fix] Resolve reconnecting issues and handle exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
ael-mouz committed May 6, 2024
1 parent bb93cd2 commit 9fb5fb7
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 44 deletions.
136 changes: 102 additions & 34 deletions app/back-end/game/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,70 @@ def get_user(user_id):
return AnonymousUser()


class GameConsumer(AsyncWebsocketConsumer):
Rooms_index = 0
rooms = {}
Room_index = 0
Rooms = {}


def get_room(room_name):
global Rooms
try:
return Rooms[room_name]
except KeyError:
print(f"Room {room_name} does not exist", file=sys.stderr)
except Exception as e:
print(f"An error occurred in get_room: {e}", file=sys.stderr)


def delete_room(room_name):
global Rooms
try:
del Rooms[room_name]
except KeyError:
print(f"Room {room_name} does not exist", file=sys.stderr)
except Exception as e:
print(f"An error occurred in delete_room: {e}", file=sys.stderr)


def add_room(room_name, room):
global Rooms
try:
Rooms[room_name] = room
except Exception as e:
print(f"An error occurred in add_room: {e}", file=sys.stderr)


def get_rooms_items():
try:
return Rooms.items()
except Exception as e:
print(f"An error occurred in iterate_rooms: {e}", file=sys.stderr)


def get_room_index():
global Room_index
try:
return Room_index
except Exception as e:
print(f"An error occurred in get_room_index: {e}", file=sys.stderr)


def increment_room_index():
global Room_index
try:
Room_index += 1
except Exception as e:
print(f"An error occurred in increment_room_index: {e}", file=sys.stderr)

# -----------------------> 0. get_room <-----------------------
def get_room(self):
return self.rooms[self.room_name]

class GameConsumer(AsyncWebsocketConsumer):
# -----------------------> 1. broadcast_message <-----------------------
async def broadcast_message(self, message):
try:
await self.channel_layer.group_send(
self.room_name, {"type": "message", "message": message}
)
except Exception as e:
print(f"An error occurred in broadcast_message: {e}")
print(f"An error occurred in broadcast_message: {e}", file=sys.stderr)

# -----------------------> 2. message <-----------------------
async def message(self, event):
Expand All @@ -57,18 +105,15 @@ async def message(self, event):
text_data=json.dumps({"message": message, "time": current_time()})
)
except Exception as e:
print(f"An error occurred in message: {e}")
print(f"An error occurred in message: {e}", file=sys.stderr)

# -----------------------> 3. connect <-----------------------
async def connect(self):
try:
if self.scope["user"].is_authenticated:
await self.accept()
print(f"Connected to {self.channel_name}", file=sys.stderr)
self.user = await get_user(user_id=self.scope["user"].id)
print(f"User: {self.user}", file=sys.stderr)
self.room_name, self.room = await self.find_or_create_room(self.user)
print(f"Room_name: {self.room_name}", file=sys.stderr)
await self.channel_layer.group_add(self.room_name, self.channel_name)
index = self.room.get_user_index(self.user)
message = f"action: connection_ack, index: {index}, User: {self.user}, Room_name: {self.room_name}"
Expand All @@ -82,12 +127,17 @@ async def connect(self):
else:
await self.close()
except Exception as e:
print(f"An error occurred in connect: {e}")
print(f"An error occurred in connect: {e}", file=sys.stderr)

# -----------------------> 4. disconnect <-----------------------
async def disconnect(self, close_code):
# await self.channel_layer.group_discard(self.room_name, self.channel_name)
pass
try:
room = get_room(self.room_name)
room.set_reconect(self.user)
# await self.channel_layer.group_discard(self.room_name, self.channel_name)
pass
except Exception as e:
print(f"An error occurred in disconnect: {e}", file=sys.stderr)

# -----------------------> 5. receive <-----------------------
async def receive(self, text_data):
Expand All @@ -96,7 +146,7 @@ async def receive(self, text_data):
message = text_data_json["message"]
print(f"Received message: {message}")
except Exception as e:
print(f"An error occurred in receive: {e}")
print(f"An error occurred in receive: {e}", file=sys.stderr)

# -----------------------> 6. start_game <-----------------------
async def start_game(self):
Expand All @@ -106,8 +156,23 @@ async def start_game(self):
await asyncio.sleep(5)
await self.broadcast_message(f"action: start_game")
await self.init_pos()
room = self.get_room()
room = get_room(self.room_name)
while True:
if room.is_reconecting():
message = f"action: reconecting, score: user1: {room.getScores()['user1']}, user2: {room.getScores()['user2']}"
await self.broadcast_message(message)
i = 0
while room.is_reconecting():
await asyncio.sleep(1)
message = f"action: reconecting"
await self.broadcast_message(message)
if (i := i + 1) > 10:
room.end_game()
room.make_user_winner(room.get_online_user())
# delete_room(self.room_name)
message = f"action: end_game, winner: {room.get_winner()[0]}, loser: {room.get_winner()[1]}"
await self.broadcast_message(message)
return
room.ball_update()
room.ball_intersect()
room.paddle_update()
Expand All @@ -124,6 +189,7 @@ async def start_game(self):
if room.is_winner():
room.end_game()
winner, loser = room.get_winner()
# delete_room(self.room_name)
message = f"action: end_game, winner: {winner}, loser: {loser}"
await self.broadcast_message(message)
break
Expand All @@ -137,12 +203,12 @@ async def start_game(self):
await self.broadcast_message(message)
await asyncio.sleep(1 / 60)
except Exception as e:
print(f"An error occurred in connect: {e}")
print(f"An error occurred in connect: {e}", file=sys.stderr)

# -----------------------> 7. init_pos <-----------------------
async def init_pos(self):
try:
room = self.get_room()
room = get_room(self.room_name)
ball_position_z = random.uniform(-2.2, 2.2)
ball_velocity_x = 0.05 * random.choice([-1, 1])
ball_velocity_z = 0.05 * random.choice([-1, 1])
Expand All @@ -151,12 +217,12 @@ async def init_pos(self):
room.start_game()
return ball_position_z, ball_velocity_x, ball_velocity_z
except Exception as e:
print(f"An error occurred in init_pos: {e}")
print(f"An error occurred in init_pos: {e}", file=sys.stderr)

# -----------------------> 8. reset <-----------------------
async def reset(self):
try:
room = self.get_room()
room = get_room(self.room_name)
ball_position_z = random.uniform(-2.2, 2.2)
if room.ball_position["x"] < 0:
ball_velocity_x = 0.05
Expand All @@ -167,26 +233,28 @@ async def reset(self):
room.set_ball_velocity(ball_velocity_x, ball_velocity_z)
return ball_position_z, ball_velocity_x, ball_velocity_z
except Exception as e:
print(f"An error occurred in reset: {e}")
print(f"An error occurred in reset: {e}", file=sys.stderr)

# -----------------------> 5. find_or_create_room <-----------------------
async def find_or_create_room(self, user_id):
try:
for room_name, room in self.rooms.items():
if room.is_started() == True and room.is_user_joined(user_id):
room.reconecting_user(self.channel_name, user_id)
await self.message({"message": "action: reconected"})
return room_name, room
elif room.is_started() == False and not room.is_user_joined(user_id):
room.add_user(self.channel_name, user_id)
await self.message({"message": "action : joined"})
return room_name, room
self.Rooms_index += 1
new_room_name = f"room_{self.Rooms_index}"
rooms_items = get_rooms_items()
for room_name, room in rooms_items:
if not room.is_ended():
if room.is_ready() and room.is_user_joined(user_id):
room.reconecting_user(self.channel_name, user_id)
await self.message({"message": "action: reconected"})
return room_name, room
elif not room.is_ready() and not room.is_user_joined(user_id):
room.add_user(self.channel_name, user_id)
await self.message({"message": "action : joined"})
return room_name, room
increment_room_index()
new_room = RoomObject()
new_room_name = f"room_{get_room_index()}"
add_room(new_room_name, new_room)
new_room.add_user(self.channel_name, user_id)
await self.message({"message": "action: created + joined"})
self.rooms[new_room_name] = new_room
return new_room_name, new_room
except Exception as e:
print(f"An error occurred in find_or_create_room: {e}")
print(f"An error occurred in find_or_create_room: {e}", file=sys.stderr)
45 changes: 35 additions & 10 deletions app/back-end/game/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ class RoomObject:
def __init__(self):
# game state
self.game_started = False
self.index = 1
self.game_ended = False
self.reconect = False
self.room_is_full = False

# ball
self.ball_radius = 0.1
Expand All @@ -20,21 +22,34 @@ def __init__(self):
self.paddle2_position = {"x": 4.8, "z": 0}

# users
self.reconect_user = ""
self.Original_users = {
"user1": {"joined": 0, "user_id": "", "index": 1, "channel_name": ""},
"user2": {"joined": 0, "user_id": "", "index": 2, "channel_name": ""},
}
self.score = {"user1": 0, "user2": 0}

# distructor
def __del__(self):
print("Room deleted")
# ------------------------> game <------------------------

def start_game(self):
self.game_started = True

def end_game(self):
self.game_started = False
self.reconect = False
self.game_ended = True

def is_started(self):
return self.game_started

def is_ended(self):
return self.game_ended

def is_reconecting(self):
return self.reconect
# ------------------------> user <------------------------
def get_winner(self):
if self.score["user1"] == 7:
Expand Down Expand Up @@ -92,22 +107,32 @@ def add_user(self, channel_name, user_id):
self.Original_users["user2"]["channel_name"] = channel_name
self.Original_users["user2"]["user_id"] = user_id
self.Original_users["user2"]["joined"] = 1
self.room_is_full = True

def reconecting_user(self, channel_name, user_id):
if self.Original_users["user1"]["user_id"] == user_id:
self.Original_users["user1"]["channel_name"] = channel_name
elif self.Original_users["user2"]["user_id"] == user_id:
self.Original_users["user2"]["channel_name"] = channel_name
self.reconect = False

def set_reconect(self,user_id):
if self.game_ended == False:
self.reconect_user = user_id
self.reconect = True

# def remove_user(self, user_id):
# if self.Original_users["user1"]["user_id"] == user_id:
# self.Original_users["user1"]["joined"] = 0
# self.Original_users["user1"]["user_id"] = ""
# self.Original_users["user1"]["channel_name"] = ""
# elif self.Original_users["user2"]["user_id"] == user_id:
# self.Original_users["user2"]["joined"] = 0
# self.Original_users["user2"]["user_id"] = ""
# self.Original_users["user2"]["channel_name"] = ""
def get_online_user(self):
# check if the both users are online
if self.Original_users["user1"]["user_id"] == self.reconect_user:
return self.Original_users["user2"]["user_id"]
if self.Original_users["user2"]["user_id"] == self.reconect_user:
return self.Original_users["user1"]["user_id"]

def make_user_winner(self, user_id):
if self.Original_users["user1"]["user_id"] == user_id:
self.score["user1"] = 7
elif self.Original_users["user2"]["user_id"] == user_id:
self.score["user2"] = 7

# ------------------------> ball <------------------------
def set_ball_position(self, x, z):
Expand Down

0 comments on commit 9fb5fb7

Please sign in to comment.