feat(presence): add presence channel handling in real-time updates
This commit is contained in:
parent
6d9b0ed8d8
commit
0eba54b8b8
3 changed files with 18 additions and 0 deletions
|
|
@ -29,6 +29,7 @@ export async function GET(req: NextRequest) {
|
|||
send: (data) => controller.enqueue(encoder.encode(data)),
|
||||
userId: user ? Number(user.id) : undefined,
|
||||
events: channel ? new Set(["presence"]) : undefined,
|
||||
presenceChannel: channel ?? undefined,
|
||||
};
|
||||
subscribe(client);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export function useRealtimePresence(channel: string, active: boolean, observe =
|
|||
} catch {
|
||||
return;
|
||||
}
|
||||
if (detail.channel !== channel) return;
|
||||
if (detail.action === "snapshot") setParticipants(detail.participants ?? []);
|
||||
if ((detail.action === "join" || detail.action === "update") && detail.participant) {
|
||||
setParticipants((current) => [
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ export interface SSEEventClient {
|
|||
send: (data: string) => void;
|
||||
events?: Set<string>;
|
||||
userId?: number;
|
||||
presenceChannel?: string;
|
||||
}
|
||||
|
||||
const clients = new Set<SSEEventClient>();
|
||||
|
|
@ -21,8 +22,23 @@ export function clientCount(): number {
|
|||
|
||||
export function broadcast(event: string, data: unknown): number {
|
||||
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
||||
const presenceChannel =
|
||||
event === "presence" &&
|
||||
typeof data === "object" &&
|
||||
data !== null &&
|
||||
"channel" in data &&
|
||||
typeof data.channel === "string"
|
||||
? data.channel
|
||||
: undefined;
|
||||
for (const client of clients) {
|
||||
if (client.events && !client.events.has(event)) continue;
|
||||
if (
|
||||
event === "presence" &&
|
||||
client.presenceChannel !== undefined &&
|
||||
client.presenceChannel !== presenceChannel
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
client.send(payload);
|
||||
} catch {
|
||||
|
|
|
|||
Loading…
Reference in a new issue