Hoppa till huvudinnehåll

Avsnitt

Teknik

Duelis verkliga teknikstack i två lager: en förklaring i vardagligt språk och en ingenjörsmässig vy.

Denna sida förklarar de teknologier Dueli faktiskt använder, i två lager: en vy i vardagligt språk för alla och en ingenjörsvy för specialister. Ingen teknologi listas om inte den nuvarande koden använder den.

I enkla ordalag

Dueli körs i webbläsaren på Cloudflares globala nätverk. Två tävlare möts i ett direktskräddat videosamtal mellan sina enheter (WebRTC peer-to-peer); när ett nätverk blockerar den direkta vägen hjälper ett TURN-relä anslutningen fram.

Under en tävling kombinerar webbläsaren de båda kamerabilderna till en enda bild och spelar in den som korta 5-sekundersblock. Blocken laddas upp allt eftersom de skapas, kan spelas upp i ordning och sammanfogas till en fullständig repris efter att matchen avslutats.

Inspelade tävlingar kan laddas ner som en MP4-fil. När en inspelning behöver konverteras sker konverteringen i besökarens webbläsare med FFmpeg.wasm, så att filen inte skickas till en extern konverteringstjänst.

Plattformens data finns i D1, sidor och API:er är byggda med Hono och TypeScript på Cloudflare, och gränssnittet använder Tailwind CSS. Liveuppdateringar kommer via SSE och polling.

För ingenjörer

Körtid: Cloudflare Pages/Workers med Hono 4 på TypeScript. D1 (SQLite) är databasen. Vite bygger Worker-paketet, Tailwind CSS 4 stylar gränssnittet och esbuild paketerar webbläsarens startpunkter.

Live media: en RTCPeerConnection i webbläsaren bär WebRTC mellan värd och motståndare. ICE-servrar utfärdas per session från GET /api/signaling/ice-servers; Cloudflare Calls TURN (TURN_TOKEN_ID och TURN_API_TOKEN) eller självhostad coturn (TURN_URL och TURN_SECRET) kan fungera som relä, med en ren STUN-reservväg när ingendera är konfigurerad.

Inspelning: en canvas-kompositör ritar båda bildströmmarna och MediaRecorder levererar ett block var femte sekund. Värden registrerar varje block vid POST /api/chunks/register (en kortlivad engångsnyckel knuten till tävlingen, ordningsföljden och byte-taket), laddar upp det, verifierar det med GET /verify och rapporterar POST /receipt. Uppspelning läser GET /api/chunks/playlist/:id, och det befintliga slutförandesteget producerar VOD:en.

Nedladdningar: @ffmpeg/core 0.12.10 körs i en självhostad webbläsarworker för MP4-konvertering, med en strukturell remux-väg för inspelningar som redan är MP4-kompatibla. Förlopp och minnesgränser hanteras i klienttjänsten.

Realtid: SSE via GET /api/sse bär liveuppdateringarna, och signalering använder HTTP-polling; produktionsvägen använder inte WebSocket.

Kvalitet: Vitest täcker enhets- och UI-kontrakt, och Playwright täcker webbläsarflödena hela vägen. Markdown-dokument renderas med marked, och PostCSS med Autoprefixer fullbordar CSS-pipelinen.

Stacken i detta repo

  • Cloudflare Pages / Workers Hosting och serverkörtid
  • Cloudflare D1 (SQLite) Applikationsdatabas
  • Hono 4 HTTP-rutter, sidor och API
  • TypeScript 5 Typad källkod för server och klient
  • Tailwind CSS 4 + PostCSS + Autoprefixer Gränssnittsstyling och CSS-pipeline
  • Vite 7 + esbuild Worker-paket och webbläsarens startpunkter
  • WebRTC (RTCPeerConnection) + TURN/STUN Ljud och video i realtid mellan deltagarna
  • Canvas compositor + MediaRecorder 5-sekundersinspelade block i webbläsaren
  • FFmpeg.wasm (@ffmpeg/core 0.12.10) MP4-konvertering och nedladdning i webbläsaren
  • marked 17 Markdown-rendering för hanterade dokument
  • Vitest 5 Testsvit för enheter och UI
  • Playwright End-to-end-webbläsartester
  • Wrangler 4 Utvecklings- och driftsättningsverktyg för Cloudflare
  • SSE + HTTP polling Liveuppdateringar utanför mediavägen

Listan är begränsad till vad package.json och repot faktiskt innehåller. Det är en teknisk beskrivning, inte ett påstående om partnerskap eller rekommendation.

Tillbaka till guidens startsida