Programmering av WebSockets och system i realtid · Lektion

Dubbelriktad strömning och flödeskontroll

Förstå hur ni hanterar kontinuerliga dataströmmar i båda riktningarna och implementerar grundläggande flödeskontroll.

Lektion 3 av 411 steg

Dubbelriktad strömning och flödeskontroll är en gratis lektion i Programmering av WebSockets och system i realtid på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Programmering av WebSockets och system i realtid, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Programmering av WebSockets och system i realtid innehåller totalt 4 lektioner.

Bortom enkla meddelanden

Hittills har vi främst betraktat WebSockets som ett sätt att skicka separata meddelanden fram och tillbaka. Men vad gör ni om ni behöver överföra en kontinuerlig dataström?

Det är här dubbelriktad strömning kommer in. Det handlar om att upprätthålla ett jämnt, pågående dataflöde samtidigt i båda riktningarna, inte bara isolerade meddelanden.

Varför dubbelriktad strömning är viktig

Föreställ er situationer som:

  • Live-ljud och video: Skicka och ta emot medieströmmar i realtid.
  • Överföring av stora filer: Ladda upp eller ner stora filer i delar.
  • Analys i realtid: Kontinuerliga uppdateringar av instrumentpaneler med stora datamängder.

I sådana fall är en konstant dataflod mer effektiv än många små, separata droppar.

Utmaningen med dataflödet

Vad händer om den ena sidan skickar data mycket snabbare än den andra hinner bearbeta den? Föreställ er en brandslang som fyller en liten kopp med vatten.

Mottagarens tillfälliga lagring (som kallas en buffer) fylls snabbt. Det kan leda till:

  • Dataförlust
  • Försämrad systemprestanda
  • Slut på minne

Det här är ett allvarligt problem vid kontinuerliga dataflöden.

Introduktion till flödeskontroll

För att förhindra att en mottagare överbelastas använder vi flödeskontroll. Det är en mekanism som reglerar hastigheten på dataöverföringen mellan en avsändare och en mottagare.

Huvudmålet är att säkerställa att avsändaren inte skickar data snabbare än mottagaren hinner hantera, så att kommunikationen blir smidig och tillförlitlig.

Viktiga begrepp inom flödeskontroll

Flödeskontroll bygger på några grundläggande idéer:

  • Buffring: Tillfällig lagring av data som har skickats men ännu inte bearbetats av mottagaren.
  • Mottryck: En signal från mottagaren till avsändaren som anger att den behöver sänka hastigheten eller pausa.
  • Pausa/återuppta: Uttryckliga kommandon eller implicita beteenden som stoppar och startar dataflödet igen.

Tänk på det som ett trafikljus för er dataström.

WebSocket-buffring i Node.js

När ni använder ws.send(data) i Node.js hanterar biblioteket ws en intern buffer för utgående meddelanden.

Metoden ws.send() returnerar ett booleskt värde:

  • true: Data skickades direkt eller buffrades utan problem.
  • false: Den interna buffern är full. Ni bör pausa sändningen av nya data.

Ni kan också kontrollera ws.bufferedAmount, som anger hur många byte som för närvarande finns i den utgående buffern.

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', ws => {
  console.log('Client connected');

  // Check buffer size before sending
  const currentBuffer = ws.bufferedAmount;
  console.log(`Current buffer size: ${currentBuffer} bytes`);

  const ok = ws.send('Hello, streaming!');
  if (!ok) {
    console.log('Buffer full right away!');
  } else {
    console.log(`Message sent. New buffer size: ${ws.bufferedAmount} bytes`);
  }

  ws.on('message', message => {
    console.log(`Received: ${message}`);
  });

  ws.on('close', () => console.log('Client disconnected'));
});

console.log('Server running on port 8080');

Mottryck på serversidan (del 1)

För att implementera flödeskontroll måste servern reagera när den utgående buffern är full. Om ws.send() returnerar false måste ni sluta skicka data tills buffern har tömts.

Det förhindrar att servern förbrukar för mycket minne eller överbelastar klientens anslutning.

Här är grundidén bakom att pausa:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', ws => {
  let messageCounter = 0;
  let isPaused = false;

  function sendLotsOfData() {
    if (isPaused) return; // Don't send if paused

    while (messageCounter < 1000) { // Send 1000 messages
      const data = `Data chunk ${messageCounter++}`;
      const ok = ws.send(data);

      if (!ok) {
        console.log('Buffer full! Pausing send...');
        isPaused = true; // Set flag to pause
        break; // Stop sending for now
      }
    }
    if (messageCounter >= 1000) {
      console.log('All data chunks sent!');
    }
  }

  sendLotsOfData(); // Start sending

  ws.on('message', msg => {}); // Placeholder
  ws.on('close', () => {}); // Placeholder
});

Mottryck på serversidan (del 2)

När buffern har tömts tillräckligt för mer data skickar biblioteket ws en händelse av typen 'drain'. Det är er signal att återuppta sändningen!

Genom att kombinera returvärdet från ws.send() med händelsen 'drain' skapar ni en robust flödeskontroll på serversidan.

Prova att köra det här kompletta exemplet. Ni kommer att se meddelandena 'Buffer full!' och 'Buffer drained!' när flödeskontrollen aktiveras.

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', ws => {
  console.log('Client connected. Starting data stream...');

  let messageCounter = 0;
  let isSending = false; // Flag to manage sending state

  function streamData() {
    if (isSending) return; // Already sending, wait for drain or completion

    isSending = true;
    while (messageCounter < 500) { // Simulate sending 500 messages
      const data = `Stream chunk ${messageCounter++} from server.`;
      const ok = ws.send(data);

      if (!ok) {
        console.log(`Buffer full (${ws.bufferedAmount} bytes), pausing send...`);
        isSending = false; // Stop sending until drain
        break; // Exit loop, wait for drain
      }
    }
    if (messageCounter >= 500) {
      console.log('Finished sending all stream chunks.');
      isSending = false;
    }
  }

  streamData(); // Start sending data after connection

  ws.on('drain', () => {
    console.log('Buffer drained, resuming send.');
    streamData(); // Resume sending
  });

  ws.on('message', message => {
    console.log(`Received from client: ${message}`);
    // In a real app, client might also stream data here,
    // requiring similar flow control logic on the client side.
  });

  ws.on('close', () => console.log('Client disconnected'));
  ws.on('error', error => console.error('WebSocket error:', error));
});

console.log('WebSocket server started on port 8080. Connect a client to see streaming.');

Flödeskontroll på klientsidan

Exemplet på serversidan fokuserar på utgående data, men klienter behöver också hantera inkommande strömmar och eventuellt sina egna utgående strömmar.

På klienten (JavaScript i webbläsaren):

  • Vid mottagning av data kan ni buffra inkommande meddelanden om bearbetningen går långsamt.
  • Vid sändning av stora datamängder (till exempel filuppladdningar) skickar ni data i delar och kan behöva bekräftelser från servern eller uttryckliga signaler om att pausa för att implementera mottryck på klientsidan.

Grundprinciperna är desamma: skicka inte snabbare än mottagaren hinner hantera.

Snabb kontroll: logik för flödeskontroll

Anta att en Node.js-baserad WebSocket-server försöker skicka en stor mängd data till en klient. Vilka av följande påståenden om flödeskontroll på serversidan är SANNA?

Sammanfattning: bemästra realtidsströmmar

I den här lektionen utforskade vi dubbelriktad strömning och det viktiga konceptet flödeskontroll i WebSockets.

  • Dubbelriktad strömning möjliggör ett kontinuerligt, samtidigt dataflöde, vilket passar utmärkt för exempelvis livevideo eller stora dataöverföringar.
  • Flödeskontroll, med mekanismer som buffring, mottryck och händelsen 'drain', förhindrar att vare sig avsändaren eller mottagaren överbelastas.
  • En korrekt implementerad flödeskontroll är avgörande för att bygga robusta, högpresterande och tillförlitliga realtidsapplikationer.

Ha dessa principer i åtanke när ni bygger nästa strömmande WebSocket-applikation!

Gratis att börja

Lär dig Programmering av WebSockets och system i realtid med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
12
Lektioner
47

Vanliga frågor

Är lektionen ”Dubbelriktad strömning och flödeskontroll” gratis?

Ja – hela texten till ”Dubbelriktad strömning och flödeskontroll” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Programmering av WebSockets och system i realtid, kan Ni uppgradera till CoddyKit PRO. Kursen i Programmering av WebSockets och system i realtid innehåller totalt 4 lektioner.

Vad lär jag mig i ”Dubbelriktad strömning och flödeskontroll”?

Förstå hur ni hanterar kontinuerliga dataströmmar i båda riktningarna och implementerar grundläggande flödeskontroll. Ni övar på Programmering av WebSockets och system i realtid med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Programmering av WebSockets och system i realtid?

Du behöver inga förkunskaper. Utbildningen i Programmering av WebSockets och system i realtid på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Dubbelriktad strömning och flödeskontroll”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Programmering av WebSockets och system i realtid-lektionen?

Ja. Varje Programmering av WebSockets och system i realtid-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Implementera publicera/prenumerera-meddelanden
  2. Request-response över WebSockets
  3. Dubbelriktad strömning och flödeskontroll
  4. Backpressure och batchning av meddelanden
← Tillbaka till Programmering av WebSockets och system i realtid