Jak wdrożyć rozmowy wideo w Next.js

Rozmowa wideo wygląda na jedną funkcję, a w aplikacji Next.js składa się z kilku. Dwie przeglądarki muszą się odnaleźć i uzgodnić, jak się połączą. Osoba, do której ktoś dzwoni, musi usłyszeć dzwonek na dowolnej stronie, na której akurat jest. Niektóre sieci nigdy nie przepuszczają połączenia bezpośredniego. A zanim to wszystko nastąpi, Twoja aplikacja musi zdecydować, kto może dzwonić do kogo.
Większość tutoriali kończy się na dwóch przeglądarkach na jednej stronie, które ręcznie wymieniają się ofertami. Ten wpis omawia każdy element, którego potrzebuje prawdziwa aplikacja, na pełnym działającym przykładzie: serwisie randkowym z naszego przewodnika po Next.js, w którym dwoje użytkowników idzie na randkę wideo w swoim czacie. Możesz wypróbować go na żywo: wybierz, kim chcesz być, potem otwórz go w oknie prywatnym, wybierz kogoś innego i zadzwoń.
Czego potrzebuje rozmowa wideo
- Sygnalizacja i dzwonienie. Zanim pojawi się jakikolwiek obraz, obie przeglądarki wymieniają przez serwer oferty i kandydatów sieciowych, a osoba, do której ktoś dzwoni, musi usłyszeć dzwonek w każdej otwartej karcie. To wymaga połączeń otwartych przez cały czas, których funkcja serverless nie utrzyma (dlaczego i co z tym zrobić).
- Droga między przeglądarkami. Bezpośrednio, gdy pozwalają na to ich sieci, a przez przekaźnik, gdy nie pozwalają (czym są serwery STUN i TURN).
- Kto może dzwonić do kogo. Reguła na Twoim serwerze, oparta na danych Twojej aplikacji, sprawdzana, zanim cokolwiek zadzwoni.
- Kamera i mikrofon. Jedno pytanie przeglądarki o zgodę, przełączanie urządzeń, wyciszanie i wyłączanie kamery.
- Ekran rozmowy. Dzwonienie, odbieranie i odrzucanie, oba obrazy wideo, czas trwania, rozłączanie.
- Serwery mediów, gdy w rozmowie jest więcej niż dwie osoby (jak działają rozmowy grupowe).
Każdy z tych elementów możesz zbudować sam na WebRTC. Możesz też oddać połączenia, dzwonienie i przekaźniki chmurze czasu rzeczywistego, a na swoim serwerze zostawić jedyną część, która naprawdę należy do Ciebie: regułę. Tak właśnie robi serwis randkowy, z WordPlus Cloud.
Przykład: randki wideo w serwisie randkowym
Użytkownicy serwisu znajdują osoby, których szukają, widzą, kto jest online, czatują i umawiają się na randkę wideo, zanim spotkają się osobiście. To aplikacja Next.js z App Routerem i bazą Postgres, a jej część czasu rzeczywistego to kilka plików. Rozmowy powstają w niej w czterech krokach.
1. Kto może dzwonić do kogo
W serwisie randkowym dwie osoby mogą ze sobą rozmawiać, gdy każda z nich szuka drugiej i żadna nie zablokowała drugiej. Serwis ma tę regułę w jednym miejscu, jako canMeet, a czat to numer z listą uczestników. mayChat mówi, że ktoś może korzystać z czatu, gdy jest jednym z jego uczestników i nadal może spotkać się z każdym z pozostałych. Rozmowy są deklarowane nazwą pokoju czatu, z tą regułą dla obu osób:
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;
});Reguła działa dla osoby, która dzwoni, i jeszcze raz dla osoby, do której ktoś dzwoni, gdy ta odbiera. Dzięki temu blokada działa od razu: od chwili, gdy jedna osoba zablokuje drugą, canMeet odpowiada „nie”, a następna rozmowa zostaje odrzucona.
2. Gdzie działa reguła
Gdy strona chce zadzwonić albo odebrać, najpierw pyta własny serwer serwisu, w route handlerze:
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() to własne logowanie serwisu, więc sesja działa tu tak samo jak na każdej innej stronie. Gdy reguła odpowiada „tak”, strona dostaje przepustkę podpisaną sekretem aplikacji, a WordPlus Cloud za jej pomocą dzwoni do drugiej osoby. Route handler odpowiada w jednym krótkim żądaniu, a do tego hosting serverless nadaje się idealnie.
3. Dzwonek na każdej stronie
Layout stron dla zalogowanych użytkowników łączy się raz i renderuje ekran rozmowy obok stron:
'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 /> znajduje się wewnątrz RealtimeProvider w app/(app)/layout.tsx, więc rozmowa dzwoni na każdej stronie, którą użytkownik ma otwartą, w każdej karcie i na każdym urządzeniu, i milknie wszędzie, gdy tylko zostanie odebrana w jednym miejscu. Ekran rozmowy to ten z Better Messages, rysowany we własnym drzewie React serwisu, więc obejmuje go CSS serwisu.
4. Rozmowa w czacie
W serwisie randkowym rozmowa wideo ma swoje miejsce przy korespondencji. Czat na stronie użytkownika pokazuje ją u siebie, obok wiadomości:
<Chat
rt={useRealtime()}
room={room}
to={to}
name={name}
avatar={avatar}
call
startCall={start}
/>Jego górny pasek pokazuje drugą osobę z przyciskami do dzwonienia. Przycisk wideo na karcie w katalogu otwiera czat z rozpoczynającą się rozmową (startCall), więc randka zaczyna się tam, gdzie obie osoby mogą też do siebie pisać.
Czat to tylko jedno z miejsc na rozmowę. CallButton rozpoczyna ją z dowolnego miejsca, CallSpot pokazuje rozmowy w wybranej przez Ciebie części strony, a useCalls daje Ci każdą rozmowę do narysowania własnego ekranu.
Co dostajesz w zestawie
- Jedno pytanie. Przeglądarka raz pyta o kamerę i mikrofon jednocześnie.
- Zawsze się łączy. Rozmowa między dwiema osobami idzie bezpośrednio między ich przeglądarkami, gdy to możliwe, przez przekaźniki na portach, które każda sieć zostawia otwarte, gdy to niemożliwe, a przez serwery mediów, gdy nawet one nie mogą dotrzeć, i przechodzi między tymi drogami bez rozłączania, szyfrowana na każdej z nich.
- Nie zrywa się. Połączenie, a wraz z nim rozmowa, trwa, gdy użytkownik przechodzi między stronami serwisu.
- Rozmowy grupowe na tym samym API. Pokój z większą liczbą osób działa na serwerach mediów, z własnym przyciskiem i ekranem rozmowy grupowej (rozmowy wideo dla aplikacji).
Wypróbuj, a potem zbuduj własną aplikację
W demo na żywo jedenaście osób należy tylko do Ciebie przez dobę, więc nikt inny nie widzi, co tam piszesz ani do kogo dzwonisz. Pod każdą stroną panel How this page works pokazuje kod, który ją tworzy, krok po kroku, z wartościami strony, którą masz otwartą.
Przewodnik po serwisie randkowym buduje cały serwis, z każdym plikiem jego części czasu rzeczywistego w całości, a rozmowy w Next.js pokazują wszystkie sposoby rozpoczęcia rozmowy we własnej aplikacji.
WordPlus Cloud for Apps ma cenę według jednoczesnych połączeń, od 1000 wzwyż, rozliczaną miesięcznie lub rocznie. Zobacz, co daje aplikacjom albo cennik dla aplikacji. Chcesz zapytać o swoją integrację? Napisz do nas.