Skip to Content

Joining a Room and Monitoring User Presence

In Agent8 you can join a room by calling a dedicated joinRoom function on the server. Once inside a room the room’s state (including the $users array) is updated in real time as users join or leave.

Server API

To join/leave rooms, you must call these functions:

  • $global.joinRoom(roomId?: string): Promise<string>: Joins the specified room. If no roomId is provided, the server will create a new random room and return its ID.
  • $global.leaveRoom(): Promise<string>: Leaves the current room. You can call $room.leave() instead.

You can manage all rooms through $global. These functions require explicit roomId specification.

  • $global.countRooms(): Promise<number> - Gets the total number of rooms that currently have active users.

  • $global.getAllRoomIds(): Promise<string[]> - Returns IDs of all rooms that currently have active users.

  • $global.getAllRoomStates(): Promise<any[]> - Returns an array of roomStates for all rooms with active users.

  • $global.getRoomUserAccounts(roomId: string): Promise<string[]> - Gets an array of account strings for current users in a specific room.

  • $global.countRoomUsers(roomId: string): Promise<number> - Gets the number of current users in a specific room.

  • $global.getRoomState(roomId: string): Promise<any>

  • $global.updateRoomState(roomId: string, state: any): Promise<any>

  • $global.getRoomUserState(roomId: string, account: string): Promise<any>

  • $global.updateRoomUserState(roomId: string, account: string, state: any): Promise<any>

server.js
class Server { const ROOM_MAX_USER = 2 async joinRoomWithRoomId(roomId) { if (roomId && $global.countRoomUsers(roomId) >= ROOM_MAX_USER) throw Error("Room is full") return await $global.joinRoom(roomId); } }

Client

Joining a Room from the Client

Before subscribing to room state updates, ensure you have joined the room by calling the server’s joinRoom function via a remote function call:

src/JoinRoomExample.tsx
import { useGameServer } from "@agent8/gameserver"; import { useEffect } from "react"; export default function JoinRoomExample({ roomId }) { const { connected, server } = useGameServer(); useEffect(() => { if (!connected) return; server.remoteFunction("joinRoom", [roomId]).catch(console.error); }, [connected, server, roomId]); return <div>Joining room {roomId}...</div>; }

Monitoring Room User Join and Leave Events

Agent8 provides specific event handlers to monitor when users join or leave a room in real-time:

src/RoomUserEvents.tsx
import { useGameServer } from "@agent8/gameserver"; import { useEffect, useState } from "react"; export default function RoomUserEvents({ roomId }) { const { connected, server } = useGameServer(); const [joinedUsers, setJoinedUsers] = useState([]); const [leftUsers, setLeftUsers] = useState([]); useEffect(() => { if (!connected) return; // First join the room server.remoteFunction("joinRoom", [roomId]).catch(console.error); // Monitor user join events const unsubscribeJoin = server.onRoomUserJoin(roomId, (account) => { console.log(`User joined: ${account}`); setJoinedUsers((prev) => [...prev, { account, time: new Date() }]); }); // Monitor user leave events const unsubscribeLeave = server.onRoomUserLeave(roomId, (account) => { console.log(`User left: ${account}`); setLeftUsers((prev) => [...prev, { account, time: new Date() }]); }); // Cleanup event handlers return () => { unsubscribeJoin(); unsubscribeLeave(); }; }, [connected, server, roomId]); if (!connected) return <p>Loading...</p>; return ( <div> <h3>Room Activity for: {roomId}</h3> <div style={{ display: "flex", gap: "20px" }}> <div> <h4>Joined Users</h4> {joinedUsers.length === 0 ? ( <p>No users have joined since you opened this page</p> ) : ( <ul> {joinedUsers.map((entry, i) => ( <li key={`join-${i}`}> {entry.account} - {entry.time.toLocaleTimeString()} </li> ))} </ul> )} </div> <div> <h4>Left Users</h4> {leftUsers.length === 0 ? ( <p>No users have left since you opened this page</p> ) : ( <ul> {leftUsers.map((entry, i) => ( <li key={`leave-${i}`}> {entry.account} - {entry.time.toLocaleTimeString()} </li> ))} </ul> )} </div> </div> </div> ); }

Using Room State for User Listing

IMPORTANT: The easiest way to get the number of users currently in the room from the client is to look at roomState.$users.length. For displaying the current list of users in a room, you can use the useRoomState hook:

src/RoomUsersList.tsx
import { useGameServer, useRoomState } from "@agent8/gameserver"; import { useEffect } from "react"; export default function RoomUsersList({ roomId }) { const { connected, server } = useGameServer(); const roomState = useRoomState(); useEffect(() => { if (!connected) return; server.remoteFunction("joinRoom", [roomId]).catch(console.error); }, [connected, server, roomId]); if (!connected) return <p>Loading...</p>; return ( <div> <h3>Current Users in Room: {roomId}</h3> <p>Total users: {roomState.$users?.length || 0}</p> <ul> {roomState.$users?.map((user) => ( <li key={user}>{user}</li> ))} </ul> </div> ); }

The combination of onRoomUserJoin/onRoomUserLeave events and the useRoomState hook gives you complete control over room presence monitoring in real-time.

Conclusion

By calling joinRoom on the server and using the appropriate event handlers and hooks on the client, you can dynamically manage room entry and monitor user presence in real time.

Last updated on