fix: Picker WebSocket auth, event handling, and status display
- Authenticate with JWT before subscribing to session events - Use message.type instead of message.event (matches server format) - Handle all new shard monitor events (room.connected, lobby.*, game.started, game.ended, room.disconnected) - Replace never-set 'waiting' status with 'monitoring' - Show monitoring indicator with live player count Made-with: Cursor
This commit is contained in:
@@ -8,7 +8,7 @@ import { formatLocalTime } from '../utils/dateUtils';
|
|||||||
import PopularityBadge from '../components/PopularityBadge';
|
import PopularityBadge from '../components/PopularityBadge';
|
||||||
|
|
||||||
function Picker() {
|
function Picker() {
|
||||||
const { isAuthenticated, loading: authLoading } = useAuth();
|
const { isAuthenticated, loading: authLoading, token } = useAuth();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [activeSession, setActiveSession] = useState(null);
|
const [activeSession, setActiveSession] = useState(null);
|
||||||
@@ -977,8 +977,10 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
|
|||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [loadGames]);
|
}, [loadGames]);
|
||||||
|
|
||||||
// Setup WebSocket connection for real-time player count updates
|
// Setup WebSocket connection for real-time session updates
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!token) return;
|
||||||
|
|
||||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
const wsUrl = `${protocol}//${window.location.hostname}:${window.location.port || (window.location.protocol === 'https:' ? 443 : 80)}/api/sessions/live`;
|
const wsUrl = `${protocol}//${window.location.hostname}:${window.location.port || (window.location.protocol === 'https:' ? 443 : 80)}/api/sessions/live`;
|
||||||
|
|
||||||
@@ -986,22 +988,33 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
|
|||||||
const ws = new WebSocket(wsUrl);
|
const ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
console.log('[WebSocket] Connected for player count updates');
|
console.log('[WebSocket] Connected, authenticating...');
|
||||||
// Subscribe to session events
|
ws.send(JSON.stringify({ type: 'auth', token }));
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: 'subscribe',
|
|
||||||
sessionId: parseInt(sessionId)
|
|
||||||
}));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
try {
|
try {
|
||||||
const message = JSON.parse(event.data);
|
const message = JSON.parse(event.data);
|
||||||
|
|
||||||
// Handle player count updates
|
if (message.type === 'auth_success') {
|
||||||
if (message.event === 'player-count.updated') {
|
console.log('[WebSocket] Authenticated, subscribing to session', sessionId);
|
||||||
console.log('[WebSocket] Player count updated:', message.data);
|
ws.send(JSON.stringify({ type: 'subscribe', sessionId: parseInt(sessionId) }));
|
||||||
// Reload games to get updated player counts
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const reloadEvents = [
|
||||||
|
'room.connected',
|
||||||
|
'lobby.player-joined',
|
||||||
|
'lobby.updated',
|
||||||
|
'game.started',
|
||||||
|
'game.ended',
|
||||||
|
'room.disconnected',
|
||||||
|
'player-count.updated',
|
||||||
|
'game.added',
|
||||||
|
];
|
||||||
|
|
||||||
|
if (reloadEvents.includes(message.type)) {
|
||||||
|
console.log(`[WebSocket] ${message.type}:`, message.data);
|
||||||
loadGames();
|
loadGames();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1027,7 +1040,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[WebSocket] Failed to connect:', error);
|
console.error('[WebSocket] Failed to connect:', error);
|
||||||
}
|
}
|
||||||
}, [sessionId, loadGames]);
|
}, [sessionId, token, loadGames]);
|
||||||
|
|
||||||
const handleUpdateStatus = async (gameId, newStatus) => {
|
const handleUpdateStatus = async (gameId, newStatus) => {
|
||||||
try {
|
try {
|
||||||
@@ -1303,14 +1316,14 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
|
|||||||
{/* Player Count Display */}
|
{/* Player Count Display */}
|
||||||
{game.player_count_check_status && game.player_count_check_status !== 'not_started' && (
|
{game.player_count_check_status && game.player_count_check_status !== 'not_started' && (
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
{game.player_count_check_status === 'waiting' && (
|
{game.player_count_check_status === 'monitoring' && !game.player_count && (
|
||||||
<span className="inline-flex items-center gap-1 text-xs bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200 px-2 py-1 rounded">
|
<span className="inline-flex items-center gap-1 text-xs bg-yellow-100 dark:bg-yellow-900 text-yellow-800 dark:text-yellow-200 px-2 py-1 rounded">
|
||||||
⏳ Waiting...
|
📡 Monitoring...
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{game.player_count_check_status === 'checking' && (
|
{(game.player_count_check_status === 'checking' || (game.player_count_check_status === 'monitoring' && game.player_count)) && (
|
||||||
<span className="inline-flex items-center gap-1 text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded">
|
<span className="inline-flex items-center gap-1 text-xs bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 px-2 py-1 rounded">
|
||||||
🔍 {game.player_count ? `${game.player_count} players (checking...)` : 'Checking...'}
|
📡 {game.player_count ? `${game.player_count} players` : 'Monitoring...'}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{game.player_count_check_status === 'completed' && game.player_count && (
|
{game.player_count_check_status === 'completed' && game.player_count && (
|
||||||
@@ -1406,7 +1419,7 @@ function SessionInfo({ sessionId, onGamesUpdate, playingGame, setPlayingGame })
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{/* Stop button for active checks */}
|
{/* Stop button for active checks */}
|
||||||
{isAuthenticated && (game.player_count_check_status === 'waiting' || game.player_count_check_status === 'checking') && (
|
{isAuthenticated && (game.player_count_check_status === 'monitoring' || game.player_count_check_status === 'checking') && (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleStopPlayerCountCheck(game.id)}
|
onClick={() => handleStopPlayerCountCheck(game.id)}
|
||||||
className="text-xs text-gray-500 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-400"
|
className="text-xs text-gray-500 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-400"
|
||||||
|
|||||||
Reference in New Issue
Block a user