Client (browser)

De GoPusherClient-class verbindt via WebSocket en ontvangt events in realtime. In React gebruik je meestal de useChannel-hook. Zorg dat je eerst de bestanden hebt geïnstalleerd.

useChannel-hook

De makkelijkste manier om events te ontvangen in een Client Component:

tsx
"use client";
import { useState } from "react";
import { useChannel } from "@/hooks/use-channel";

export default function Chat() {
  const [bericht, setBericht] = useState<{ gebruiker: string; tekst: string } | null>(null);

  useChannel(
    process.env.NEXT_PUBLIC_GOPUSHER_KEY!,
    "chat",
    "nieuw-bericht",
    (data) => setBericht(data),
  );

  if (!bericht) return <p>Wachten op berichten...</p>;
  return <p><b>{bericht.gebruiker}:</b> {bericht.tekst}</p>;
}

De callback wordt aangeroepen telkens als er een event binnenkomt.

Meerdere events

Gebruik meerdere hooks in hetzelfde component:

tsx
"use client";
import { useState } from "react";
import { useChannel } from "@/hooks/use-channel";

const KEY = process.env.NEXT_PUBLIC_GOPUSHER_KEY!;

export default function Dashboard() {
  const [bestelling, setBestelling] = useState<any>(null);
  const [melding, setMelding] = useState<any>(null);

  useChannel(KEY, "orders", "nieuwe-bestelling", setBestelling);
  useChannel(KEY, "notificaties", "alert", setMelding);

  return (
    <div>
      {bestelling && <p>Nieuwe bestelling: {bestelling.id}</p>}
      {melding && <p>Melding: {melding.tekst}</p>}
    </div>
  );
}

Direct met de class werken

Heb je meer controle nodig, gebruik dan GoPusherClient rechtstreeks:

tsx
"use client";
import { useEffect, useState } from "react";
import { GoPusherClient } from "@/lib/go-pusher-client";

export default function Berichten() {
  const [berichten, setBerichten] = useState<string[]>([]);

  useEffect(() => {
    const pusher = new GoPusherClient(
      process.env.NEXT_PUBLIC_GOPUSHER_KEY!,
      process.env.NEXT_PUBLIC_GOPUSHER_HOST,
    );

    pusher.connect().then(() => {
      pusher.subscribe("chat").on("chat", "nieuw-bericht", (data) => {
        setBerichten((prev) => [...prev, data.tekst]);
      });
    });

    return () => pusher.disconnect();
  }, []);

  return <ul>{berichten.map((b, i) => <li key={i}>{b}</li>)}</ul>;
}

Presence-kanaal (wie is online)

Presence-kanalen laten zien welke gebruikers verbonden zijn. Zie ook Kanalen.

tsx
"use client";
import { useEffect, useState } from "react";
import { GoPusherClient } from "@/lib/go-pusher-client";

export default function OnlineGebruikers({ userId, userName }: { userId: string; userName: string }) {
  const [leden, setLeden] = useState<Map<string, any>>(new Map());

  useEffect(() => {
    const pusher = new GoPusherClient(
      process.env.NEXT_PUBLIC_GOPUSHER_KEY!,
      process.env.NEXT_PUBLIC_GOPUSHER_HOST,
    );

    pusher.connect().then(async () => {
      await pusher.subscribePrivate(
        "presence-lobby",
        "/api/pusher/auth",
        { user_id: userId, user_info: { naam: userName } },
      );

      pusher
        .on("presence-lobby", "pusher:subscription_succeeded", (data) => {
          setLeden(new Map(Object.entries(data.presence.hash)));
        })
        .on("presence-lobby", "pusher:member_added", (data) => {
          setLeden((prev) => new Map(prev).set(data.user_id, data.user_info));
        })
        .on("presence-lobby", "pusher:member_removed", (data) => {
          setLeden((prev) => {
            const next = new Map(prev);
            next.delete(data.user_id);
            return next;
          });
        });
    });

    return () => pusher.disconnect();
  }, [userId, userName]);

  return (
    <div>
      <h3>Online ({leden.size})</h3>
      <ul>{Array.from(leden.entries()).map(([id, info]) => <li key={id}>{info.naam}</li>)}</ul>
    </div>
  );
}