Skip to content

Commit 8ab7f8b

Browse files
authored
Merge pull request #4 from martian56/fix-con-issues
Fixes Connection issues
2 parents 8b83646 + 6e0db04 commit 8ab7f8b

File tree

4 files changed

+38
-18
lines changed

4 files changed

+38
-18
lines changed

backend/main.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ async def root():
6060

6161

6262
@app.get("/health")
63+
@app.head("/health")
6364
async def health():
6465
return {"status": "healthy", "timestamp": datetime.now(UTC).isoformat()}
6566

@@ -173,6 +174,7 @@ async def websocket_endpoint(
173174
user_agent = websocket.headers.get("user-agent", "Unknown")
174175

175176
# Get or create meeting in database
177+
meeting = None
176178
async with AsyncSessionLocal() as db:
177179
try:
178180
# Find meeting by code
@@ -185,6 +187,16 @@ async def websocket_endpoint(
185187
await websocket.close(code=1008, reason="Meeting not found")
186188
return
187189

190+
# Check if this is the first active participant (make them host)
191+
# Use a transaction-safe approach to avoid race conditions
192+
existing_participants = await db.execute(
193+
select(func.count(Participant.id))
194+
.where(Participant.meeting_id == meeting.id)
195+
.where(Participant.is_active == True)
196+
)
197+
count = existing_participants.scalar() or 0
198+
is_host = count == 0
199+
188200
# Create participant record
189201
participant = Participant(
190202
meeting_id=meeting.id,
@@ -193,19 +205,9 @@ async def websocket_endpoint(
193205
ip_address=client_ip,
194206
user_agent=user_agent,
195207
is_active=True,
196-
is_host=False, # First participant becomes host
208+
is_host=is_host,
197209
)
198210

199-
# Check if this is the first participant (make them host)
200-
existing_participants = await db.execute(
201-
select(func.count(Participant.id))
202-
.where(Participant.meeting_id == meeting.id)
203-
.where(Participant.is_active == True)
204-
)
205-
count = existing_participants.scalar() or 0
206-
if count == 0:
207-
participant.is_host = True
208-
209211
db.add(participant)
210212

211213
# Log join event
@@ -221,10 +223,16 @@ async def websocket_endpoint(
221223
await db.commit()
222224
await db.refresh(participant)
223225

224-
logger.info(f"Participant {client_id} created in database for meeting {meeting_code}")
226+
logger.info(f"Participant {client_id} created in database for meeting {meeting_code} (host: {is_host})")
225227
except Exception as e:
226228
logger.error(f"Error creating participant: {e}")
227229
await db.rollback()
230+
await websocket.close(code=1011, reason="Internal server error")
231+
return
232+
233+
# Ensure meeting was found before proceeding
234+
if not meeting:
235+
return
228236

229237
# Initialize meeting connections if not exists
230238
if meeting_code not in active_connections:
@@ -459,14 +467,20 @@ async def broadcast_to_meeting(meeting_code: str, message: dict, exclude_client:
459467
if meeting_code not in active_connections:
460468
return
461469

462-
for client_id, ws in active_connections[meeting_code].items():
470+
# Create a list of connections to avoid modification during iteration
471+
connections = list(active_connections[meeting_code].items())
472+
473+
for client_id, ws in connections:
463474
if exclude_client and client_id == exclude_client:
464475
continue
465476

466477
try:
467478
await ws.send_json(message)
468479
except Exception as e:
469480
logger.error(f"Error broadcasting to {client_id}: {e}")
481+
# Remove dead connection
482+
if meeting_code in active_connections:
483+
active_connections[meeting_code].pop(client_id, None)
470484

471485

472486
async def handle_disconnect(meeting_code: str, client_id: str, client_ip: str = None):

frontend/src/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Backend API configuration
2-
export const API_BASE_URL = import.meta.env.VITE_API_URL
3-
export const WS_BASE_URL = import.meta.env.VITE_WS_URL
2+
export const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000';
3+
export const WS_BASE_URL = import.meta.env.VITE_WS_URL || 'ws://localhost:8000';
44

55
// WebRTC Configuration with Google STUN servers
66
export const RTC_CONFIG: RTCConfiguration = {

frontend/src/hooks/useWebSocket.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ export const useWebSocket = (
7373
console.log('WebSocket closed');
7474
setIsConnected(false);
7575

76-
// Attempt to reconnect after 3 seconds
76+
// Only reconnect if this wasn't an intentional close
77+
// Check if component is still mounted before reconnecting
7778
reconnectTimeoutRef.current = setTimeout(() => {
78-
if (wsRef.current?.readyState === WebSocket.CLOSED) {
79+
// Only reconnect if WebSocket is still closed and we don't have a new connection
80+
if (wsRef.current?.readyState === WebSocket.CLOSED || !wsRef.current) {
7981
connect();
8082
}
8183
}, 3000);
@@ -88,13 +90,17 @@ export const useWebSocket = (
8890

8991
useEffect(() => {
9092
connect();
93+
let isMounted = true;
9194

9295
return () => {
96+
isMounted = false;
9397
if (reconnectTimeoutRef.current) {
9498
clearTimeout(reconnectTimeoutRef.current);
99+
reconnectTimeoutRef.current = undefined;
95100
}
96101
if (wsRef.current) {
97102
wsRef.current.close();
103+
wsRef.current = null;
98104
}
99105
};
100106
}, [connect]);

frontend/src/pages/MeetingRoom.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ export default function MeetingRoom() {
229229
console.warn('Unhandled WebSocket message type:', message.type, message);
230230
break;
231231
}
232-
}, [clientId, createOffer, handleOffer, handleAnswer, handleRemoteIceCandidate, removePeer, hasPeerConnection, isInitialized]);
232+
}, [clientId, createOffer, handleOffer, handleAnswer, handleRemoteIceCandidate, removePeer, hasPeerConnection, isInitialized, localStream, chatOpen]);
233233

234234
// Normalize meeting code to lowercase for backend consistency
235235
const normalizedMeetingCode = meetingCode?.toLowerCase() || '';

0 commit comments

Comments
 (0)