Zo bouw je videogesprekken in Next.js

Een videogesprek lijkt één functie, maar in een Next.js-app zijn het er meerdere. Twee browsers moeten elkaar vinden en afspreken hoe ze verbinding maken. Wie gebeld wordt, moet het horen overgaan, op welke pagina die ook zit. Sommige netwerken laten nooit een directe verbinding door. En vóór dat alles moet je app beslissen wie wie mag bellen.
De meeste tutorials stoppen bij twee browsers op één pagina die met de hand offers uitwisselen. Dit artikel loopt elk onderdeel langs dat een echte app nodig heeft, met een compleet werkend voorbeeld: de datingsite uit onze Next.js-handleiding, waar twee leden vanuit hun chat op videodate gaan. Je kunt het live proberen: kies wie je wilt zijn, open de site daarna in een privévenster, kies daar iemand anders en bel.
Wat een videogesprek nodig heeft
- Signaling en overgaan. Voordat er beeld is, wisselen de twee browsers via een server offers en netwerkkandidaten uit, en bij wie gebeld wordt, moet het overgaan in elk tabblad dat open staat. Daarvoor zijn verbindingen nodig die de hele tijd open blijven, en die kan een serverless functie niet vasthouden (waarom, en wat je eraan kunt doen).
- Een weg tussen de browsers. Rechtstreeks als hun netwerken dat toelaten, en via een relay als dat niet lukt (STUN- en TURN-servers uitgelegd).
- Wie wie mag bellen. Een regel op je server, met de eigen data van je app, gecontroleerd voordat er bij iemand iets overgaat.
- De camera en de microfoon. Eén vraag om toestemming van de browser, wisselen van apparaat, dempen en camera uit.
- Een belscherm. Overgaan, opnemen en weigeren, beide video’s, de duur, ophangen.
- Mediaservers, zodra er meer dan twee mensen in een gesprek zitten (hoe groepsgesprekken werken).
Je kunt elk van deze onderdelen zelf bouwen op WebRTC. Of je laat een realtime cloud de verbindingen, het overgaan en de relays draaien, terwijl je server het ene deel houdt dat echt van jou is: de regel. Dat is wat de datingsite doet, via WordPlus Cloud.
Het voorbeeld: videodates op een datingsite
Leden van de site vinden de mensen die ze zoeken, zien wie er online is, chatten, en gaan op videodate voordat ze elkaar in het echt ontmoeten. Het is een Next.js-app met de App Router en Postgres, en het realtime deel bestaat uit een paar bestanden. In vier stappen krijgt de site zijn gesprekken.
1. Wie wie mag bellen
Op een datingsite mogen twee mensen met elkaar praten als ze elkaar zoeken en geen van beiden de ander heeft geblokkeerd. De site heeft die regel op één plek, als canMeet, en een chat als een nummer met zijn leden. mayChat zegt dat iemand een chat mag gebruiken als die persoon een van de leden is en elk ander lid nog steeds mag ontmoeten. Gesprekken worden vastgelegd op de naam van de ruimte van de chat, met die regel voor beide mensen:
realtime.calls('chat:{id}', async (user, other, { id }) => {
// The one asking: who calls, as they call, or who is called, as they answer.
const userMayChat = await mayChat(user, id);
// The other one of the call.
const otherMayChat = await mayChat(other, id);
return userMayChat && otherMayChat;
});De regel draait voor wie belt, en nog een keer voor wie gebeld wordt, zodra die opneemt. Een blokkade werkt dus meteen: vanaf het moment dat de een de ander blokkeert, zegt canMeet nee, en wordt het volgende gesprek geweigerd.
2. Waar de regel draait
Wil een pagina bellen of opnemen, dan vraagt ze dat eerst aan de eigen server van de site, in een route handler:
import { currentUserId } from '@/lib/auth';
import { realtime } from '@/lib/realtime';
export async function POST(request: Request) {
// JSON only, which a page of another site can't send here.
if (!request.headers.get('content-type')?.includes('application/json')) {
return new Response(null, { status: 415 });
}
const ask = await request.json();
const user = await currentUserId();
const pass = await realtime.authorizeCall(ask, user);
return Response.json(pass);
}currentUserId() is de eigen login van de site, dus de sessie werkt hier net als op elke andere pagina. Zegt de regel ja, dan krijgt de pagina een toegangsbewijs, ondertekend met de geheime sleutel van de app, en daarmee laat WordPlus Cloud het bij de ander overgaan. De route antwoordt in één kort verzoek, en daar is serverless hosting juist goed in.
3. Overgaan op elke pagina
De layout van de pagina’s achter de login maakt één keer verbinding en rendert het belscherm naast de pagina’s:
'use client';
import '@wordplus/realtime-ui/calls.css';
import '@wordplus/realtime-ui/chat.css';
import { useRealtime } from '@wordplus/realtime/react';
import { CallScreen } from '@wordplus/realtime-ui/react';
export function Screens() {
return <CallScreen rt={useRealtime()} />;
}<Screens /> staat binnen RealtimeProvider in app/(app)/layout.tsx, dus een gesprek gaat over op elke pagina die een lid open heeft, in elk tabblad en op elk apparaat, en houdt overal op met overgaan zodra het op één ervan is opgenomen. Het belscherm is dat van Better Messages, getekend in de eigen React-tree van de site, zodat de CSS van de site het bereikt.
4. Het gesprek in de chat
Op een datingsite hoort het gesprek bij de conversatie. De chat op de pagina van een lid toont het gesprek zelf, naast de berichten:
<Chat
rt={useRealtime()}
room={room}
to={to}
name={name}
avatar={avatar}
call
startCall={start}
/>De balk bovenaan toont de ander met de belknoppen. Een knop Video op een kaart in de catalogus opent de chat en start meteen het gesprek (startCall), zodat de date begint waar de twee elkaar ook kunnen schrijven.
De chat is maar één plek voor een gesprek. Een CallButton start er een vanaf elke plek, een CallSpot toont gesprekken in een deel van de pagina dat jij kiest, en useCalls geeft je elk gesprek, zodat je je eigen scherm kunt tekenen.
Wat je erbij krijgt
- Eén vraag. De browser vraagt één keer om de camera en de microfoon samen.
- Het komt altijd door. Een gesprek tussen twee mensen gaat rechtstreeks tussen hun browsers als dat kan, via relays op de poorten die elk netwerk openlaat als dat niet kan, en via mediaservers als zelfs die er niet doorheen komen. Het wisselt daartussen zonder op te hangen, en is op elke weg versleuteld.
- Het blijft staan. De verbinding, en daarmee het gesprek, blijft bestaan terwijl het lid tussen de pagina’s van de site wisselt.
- Groepsgesprekken op dezelfde API. Een ruimte met meer mensen draait op mediaservers, met een eigen knop en scherm voor groepsgesprekken (videogesprekken voor apps).
Eerst proberen, dan zelf bouwen
In de live demo zijn de elf mensen een dag lang alleen van jou, dus wat je er ook schrijft of wie je ook belt, niemand anders ziet het. Onder elke pagina toont How this page works stap voor stap de code die de pagina maakt, met de waarden van de pagina die je open hebt.
De handleiding voor de datingsite bouwt de hele site, met elk bestand van de realtime kant volledig uitgeschreven, en gesprekken in Next.js laat elke manier zien om in je eigen app een gesprek te starten.
WordPlus Cloud for Apps is geprijsd op gelijktijdige verbindingen, vanaf 1.000, maandelijks of jaarlijks gefactureerd. Bekijk wat het doet voor apps, of de prijzen voor apps. Vragen over je integratie? Schrijf ons.