Realtid, sikkerhed og stabil drift

Live-opdateringer i appen: sikre forbindelser uden mistede beskeder

En grøn “forbundet”-indikator beviser ikke, at brugeren har de rigtige data. En WebSocket eller anden live-forbindelse kan falde ud ved netværksskift, en ny release eller en udløbet session. Appen skal derfor kunne opdage huller, afvise dubletter og kontrollere adgang til hver handling – også efter genforbindelse.

Udgivet 7. november 2026 · Ca. 12 minutters læsetid

Aftal hvad “live” skal betyde

Realtid er ikke ét teknisk løfte. Et dashboard, en chat og en godkendelseshandling kan have helt forskellige krav. Beskriv derfor brugerens forventning, før I vælger WebSocket, Server-Sent Events, polling eller en platforms eget realtime-SDK.

BehovRelevant modelSpørgsmål der skal besvares
Skærmen skal følge statusServer til klient via SSE, abonnement eller WebSocketHvordan hentes korrekt tilstand efter et hul?
Begge sider sender løbendeWebSocket eller et realtime-frameworkHvordan kvitteres, valideres og genbehandles beskeder?
Få ændringer og lav hastighedKontrolleret polling kan være nokHvor ofte må der spørges uden støj og unødvendigt forbrug?
Kritisk forretningshandlingAlmindeligt API-kald med entydigt resultatSkal live-kanalen kun varsle om en allerede gemt ændring?

En live-kanal bør ikke være eneste bevis for, at en betaling, godkendelse eller sletning er gennemført. Gem den autoritative ændring server-side, returnér et entydigt resultat, og brug eventuelt live-beskeden til at opdatere andre skærme.

Forbindelse, bruger og rettighed er tre forskellige ting

WebSocket-protokollen giver en vedvarende kanal, men ikke automatisk login eller adgangskontrol. Serveren skal forbinde kanalen med en gyldig identitet, kontrollere det forventede origin i browserbaserede flows og vurdere rettigheden til hver kanal, virksomhed og handling.

  1. 1. Kontrollér forbindelsen. Brug wss:// i produktion, tillad kun forventede origins, og begræns uautentificerede forbindelser.
  2. 2. Fastslå identiteten. Validér session eller token efter den valgte stacks dokumenterede model. Læg ikke tokens i URL'er, hvis de dermed kan ende i logs.
  3. 3. Kontrollér hvert abonnement. En bruger må kun tilslutte sig rum, emner eller dokumenter, som vedkommende må læse.
  4. 4. Kontrollér hver handling. Et godkendt handshake er ikke tilladelse til alle efterfølgende beskeder. Valider både handling, dataobjekt og virksomhed på serveren.
  5. 5. Håndtér udløb og logout. Luk eller genautentificér forbindelsen, når sessionen udløber, brugeren deaktiveres eller rettigheden ændres.
CORS beskytter ikke en WebSocket. Browserens handshake sender et Origin-header, men serveren skal selv kontrollere det mod en eksplicit liste. Cookies kan ellers blive sendt med en forbindelse, som er startet fra et fremmed website.

Definér en lille kontrakt for hver besked

Behandl live-beskeder som andre ubetroede API-input. Brug faste beskedtyper, versionsfelt, begrænset størrelse og server-side validering. En brugbar kontrakt gør det også muligt at skelne dubletter, gamle beskeder og ukendte klientversioner.

Eksempel på felter – ikke en universel standard

type
En tilladt handling eller hændelse, eksempelvis order.updated.
eventId
Stabil, unik reference til dubletkontrol og fejlsøgning.
version
Kontraktversion, så server og klient kan afvise eller håndtere ukendte formater tydeligt.
resourceId
Objektet, som serveren skal kontrollere adgang til – ikke en rettighed i sig selv.
sequence
Eventuel rækkefølge eller cursor inden for et klart afgrænset stream.

Tillad kun kendte felter og værdier, hvor det giver mening. Sæt grænser for beskedstørrelse, frekvens, samtidige forbindelser og abonnementer pr. bruger eller virksomhed. Undlad at logge hele beskeder, tokens eller persondata som standard.

Genforbindelse kræver mere end “prøv igen”

RFC 6455 beskriver selve forbindelsen, men appen skal selv beslutte, hvad der sker med forretningshændelser under et afbrud. Socket.IO dokumenterer eksempelvis beskedrækkefølge, men standardleveringen er højst én gang: en besked kan mangle, hvis forbindelsen brydes på det forkerte tidspunkt. Andre platforme har andre garantier, som skal læses og testes konkret.

  1. Vis forbindelsestilstanden. Skeln mellem opdateret, genforbinder, muligvis forældet og afbrudt. Et skjult udfald skaber falsk tryghed.
  2. Genforbind med stigende pause og tilfældig variation. Mange klienter må ikke ramme serveren samtidigt efter en release eller netværksfejl.
  3. Send en cursor eller senest behandlede event-ID. Serveren kan derefter levere manglende hændelser, når den valgte tjeneste understøtter det.
  4. Afvis dubletter sikkert. Genafsendelse kan være nødvendig, hvis en kvittering forsvinder. Den samme stabile ID skal derfor kunne behandles uden dobbelt effekt.
  5. Hent en frisk tilstand ved ukendt hul. Hvis historikken ikke længere kan genafspilles, skal klienten genindlæse det autoritative snapshot i stedet for at gætte.
Design efter den valgte tjeneste. Azure Web PubSub har eksempelvis pålidelige subprotokoller med sequence IDs og acknowledgements. Firebase Realtime Database har sit eget forbindelses- og synkroniseringsflow. De mekanismer kan ikke kopieres direkte til en rå WebSocket.

Adskil aktuel tilstand fra hændelser

En hændelse fortæller, at noget skete. Den aktuelle database fortæller, hvordan objektet ser ud nu. Klienten bør vide, hvilken af de to den viser. Det gør genindlæsning, fejlsøgning og konfliktløsning mere forudsigelig.

  • Notifikation: Brug beskeden som signal til at hente den nyeste tilladte tilstand.
  • Event-stream: Gem events med stabil ID, rækkefølge inden for et afgrænset scope og en retention, der passer til genafspilningen.
  • Snapshot: Giv klienten en kendt vej til at nulstille lokal state fra serverens aktuelle data.
  • Presence: Behandl “online” som et midlertidigt signal, ikke som bevis på at personen ser skærmen eller kan svare.

Flere faner og enheder kan skabe flere samtidige forbindelser for samme bruger. Presence og forbindelsesgrænser skal derfor modelleres pr. forbindelse eller enhed, hvis funktionen skal være præcis.

Beskyt serveren mod langsomme og støjende klienter

Vedvarende forbindelser bruger ressourcer, selv når de ikke flytter nyttige data. Mål derfor aktive forbindelser, beskedrate, kø eller buffer, genforbindelser og afvisninger – og beslut på forhånd, hvordan en langsom klient håndteres.

  • Begræns forbindelser, abonnementer og beskeder pr. identitet og relevant tenant.
  • Afvis for store eller ukendte beskeder tidligt, og luk gentagne protokolbrud kontrolleret.
  • Brug heartbeat eller den valgte stacks health-mekanisme til at opdage døde forbindelser.
  • Sæt en øvre grænse for udgående kø eller buffer; vælg om ikke-kritiske opdateringer må samles, droppes eller udløse et nyt snapshot.
  • Test reverse proxy, load balancer, hosting og timeoutindstillinger med den rigtige live-protokol.

Gør live-forløbet synligt i drift

Et almindeligt HTTP-accesslog viser ofte kun forbindelsens handshake. Tilføj derfor strukturerede, begrænsede hændelser for selve live-forløbet uden at gemme følsomt indhold.

  • Forbindelse åbnet og lukket med brugerreference, tenant, klientversion, varighed og årsag.
  • Mislykket autentifikation, afvist origin, afvist abonnement og manglende rettighed.
  • Valideringsfejl, rate limit, for stor besked og ukendt beskedtype.
  • Antal genforbindelser, huller, genafspillede events, dubletter og snapshot-resets.
  • En korrelationsreference, der kan forbindes med API, job, database og brugerens fejlmelding.

Alarmer bør handle om brugerens oplevelse: usædvanligt mange afbrydelser, voksende forsinkelse, manglende kvitteringer eller en pludselig stigning i afviste beskeder. Et højt antal åbne forbindelser er ikke i sig selv et kvalitetsbevis.

Test de afbrudte forløb bevidst

En demo på stabilt Wi-Fi viser kun den pæne vej. Test med den samme proxy, hosting, identitet og skalering, som produktionen bruger.

Netværk og release

Afbryd Wi-Fi, skift netværk, sæt fanen i baggrunden, genstart serveren, og udgiv en ny version mens gamle klienter er forbundet.

Login og rettigheder

Lad sessionen udløbe, log ud i en anden fane, fjern brugerens rolle, og forsøg at abonnere på en anden virksomheds kanal.

Levering og rækkefølge

Afbryd før og efter kvittering, genafsend samme event-ID, spring en sequence over, og kontrollér at klienten henter en frisk tilstand ved ukendt hul.

Belastning og misbrug

Åbn mange forbindelser, send for store eller ukendte beskeder, og afprøv en langsom modtager uden at ramme rigtige brugere.

Typiske fejl

  • “Forbundet” vises som “opdateret”: Brugeren kan se gamle data efter et ubemærket hul.
  • Rettigheden kontrolleres kun ved handshake: En lang forbindelse overlever rolleændring, logout eller deaktivering.
  • Genforbindelse starter fra nul: Klienten mister events eller udfører den samme handling to gange.
  • Alle beskeder udsendes til alle: Frontend skjuler uvedkommende data, men serveren har allerede lækket dem.
  • Ingen grænse for køen: En langsom fane bruger stadig mere hukommelse og får stadig ældre data.
  • Kun lokal udvikling testes: Proxy, timeouts, flere instanser og release-genstart opdages først i drift.

Tjekliste til stabile live-opdateringer

  • □ Hver live-funktion har et konkret krav til aktualitet, levering og fejltilstand.
  • □ Den valgte protokol og tjenestes faktiske leveringsgarantier er dokumenteret.
  • □ Produktion bruger krypteret transport og en eksplicit origin-kontrol, hvor den er relevant.
  • □ Identitet, tenant og rettighed kontrolleres på serveren for abonnementer og handlinger.
  • □ Logout, sessionudløb, deaktivering og rolleændring påvirker åbne forbindelser.
  • □ Beskedtyper, felter, størrelse, frekvens og fejl er valideret og afgrænset.
  • □ Genforbindelse bruger pause, cursor eller event-ID og en sikker snapshot-reservevej.
  • □ Dubletter kan genkendes uden at udføre den samme forretningseffekt to gange.
  • □ Brugeren kan se, når data muligvis er forældede eller forbindelsen genoprettes.
  • □ Logs og alarmer dækker afbrydelser, huller, afvisninger og voksende forsinkelse uden følsomt indhold.
  • □ Netværksbrud, release, sessionudløb, flere faner og belastning er testet i et realistisk miljø.

Relaterede guides

Officielle kilder

WebSocket-biblioteker og managed realtime-tjenester har forskellige garantier. Kontrollér altid den dokumentation, som gælder for jeres konkrete version og arkitektur.