Programmeren van WebSockets en realtime-systemen · Les

Bidirectionele streaming en flow control

Begrijp hoe u continue datastromen in beide richtingen beheert en basisprincipes van flow control implementeert.

Les 3 van 411 stappen

Bidirectionele streaming en flow control is een gratis Programmeren van WebSockets en realtime-systemen-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Programmeren van WebSockets en realtime-systemen. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Programmeren van WebSockets en realtime-systemen bevat in totaal 4 lessen.

Verder dan eenvoudige berichten

Tot nu toe hebben we WebSockets vooral gezien als een manier om afzonderlijke berichten heen en weer te sturen. Maar wat als je een voortdurende gegevensstroom moet overbrengen?

Hier komt bidirectionele streaming van pas. Daarbij houd je in beide richtingen tegelijk een constante, voortdurende gegevensstroom in stand, in plaats van alleen losse berichten te versturen.

Waarom bidirectionele streaming belangrijk is

Stel je situaties voor zoals:

  • Live audio/video: realtime-mediastromen versturen en ontvangen.
  • Overdracht van grote bestanden: grote bestanden in delen uploaden of downloaden.
  • Realtime analyses: dashboards voortdurend bijwerken met grote hoeveelheden gegevens.

In deze situaties is een constante 'rivier' van gegevens efficiënter dan veel kleine, afzonderlijke 'druppels'.

De uitdaging van de gegevensstroom

Wat gebeurt er als de ene kant veel sneller gegevens verstuurt dan de andere kant ze kan verwerken? Denk aan een brandslang die water in een klein kopje giet.

De tijdelijke opslag van de ontvanger (een buffer genoemd) loopt snel vol. Dit kan leiden tot:

  • Gegevensverlies
  • Vertragingen in het systeem
  • Uitputting van het geheugen

Dit is een kritiek probleem bij een voortdurende gegevensstroom.

Flow control introduceren

Om te voorkomen dat een ontvanger wordt overspoeld, gebruiken we flow control. Dit is een mechanisme dat de snelheid van de gegevensoverdracht tussen een verzender en een ontvanger beheert.

Het belangrijkste doel is ervoor te zorgen dat de verzender geen gegevens sneller verstuurt dan de ontvanger kan verwerken. Zo blijft de communicatie soepel en betrouwbaar.

Belangrijke concepten van flow control

Flow control steunt op enkele basisideeën:

  • Buffering: tijdelijke opslag voor gegevens die zijn verstuurd maar nog niet door de ontvanger zijn verwerkt.
  • Backpressure: een signaal van de ontvanger naar de verzender dat die moet vertragen of pauzeren.
  • Pauzeren/hervatten: expliciete opdrachten of impliciet gedrag om de gegevensstroom te stoppen en opnieuw te starten.

Zie het als een verkeerslicht voor je gegevensstroom.

WebSocket-buffering in Node.js

Wanneer je ws.send(data) gebruikt in Node.js, beheert de bibliotheek ws een interne buffer voor uitgaande berichten.

De methode ws.send() retourneert een boolean:

  • true: de gegevens zijn direct verstuurd of succesvol gebufferd.
  • false: de interne buffer is vol. Je moet stoppen met het versturen van nieuwe gegevens.

Je kunt ook ws.bufferedAmount controleren. Dit geeft aan hoeveel bytes zich momenteel in de uitgaande buffer bevinden.

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');

Backpressure aan serverzijde (deel 1)

Om flow control te implementeren, moet je server reageren wanneer zijn uitgaande buffer vol is. Als ws.send() false retourneert, moet je stoppen met het versturen van gegevens totdat de buffer leeg genoeg is.

Zo voorkom je dat de server te veel geheugen gebruikt of de verbinding van de client overbelast.

Dit is het basisidee achter pauzeren:

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
});

Backpressure aan serverzijde (deel 2)

Wanneer de buffer voldoende is leeggelopen voor meer gegevens, verstuurt de bibliotheek ws een gebeurtenis 'drain'. Dat is het signaal om het versturen te hervatten!

Door de retourwaarde van ws.send() te combineren met de gebeurtenis 'drain' krijg je robuuste flow control aan serverzijde.

Probeer dit volledige voorbeeld uit. Je ziet de berichten 'Buffer full!' en 'Buffer drained!' wanneer flow control actief wordt.

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.');

Flow control aan clientzijde

Hoewel het voorbeeld aan serverzijde zich richt op uitgaande gegevens, moeten clients ook binnenkomende stromen en mogelijk hun eigen uitgaande stromen beheren.

Op de client (JavaScript in de browser):

  • Bij het ontvangen van gegevens kun je binnenkomende berichten bufferen als de verwerking traag verloopt.
  • Bij het versturen van grote hoeveelheden gegevens (bijvoorbeeld bestanduploads) verstuur je de gegevens in delen. Mogelijk heb je bevestigingen van de server of expliciete signalen voor 'pauzeren' nodig om backpressure aan clientzijde te implementeren.

De basisprincipes blijven hetzelfde: verstuur niet sneller dan de ontvanger kan verwerken.

Snelle controle: logica van flow control

Stel je een Node.js WebSocket-server voor die een grote hoeveelheid gegevens naar een client probeert te versturen. Welke van de volgende uitspraken over het implementeren van flow control aan serverzijde zijn WAAR?

Samenvatting: realtime stromen beheersen

In deze les hebben we bidirectionele streaming en het belangrijke concept flow control in WebSockets onderzocht.

  • Bidirectionele streaming maakt een voortdurende, gelijktijdige gegevensstroom mogelijk. Dit is ideaal voor toepassingen zoals livevideo of overdracht van grote hoeveelheden gegevens.
  • Flow control voorkomt met mechanismen zoals buffering, backpressure en de gebeurtenis 'drain' dat de verzender of ontvanger wordt overspoeld.
  • De juiste implementatie van flow control is essentieel voor robuuste, krachtige en betrouwbare realtime toepassingen.

Houd deze principes in gedachten wanneer je je volgende streaming-WebSockettoepassing bouwt!

Gratis beginnen

Leer Programmeren van WebSockets en realtime-systemen met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
12
Lessen
47

Veelgestelde vragen

Is de les “Bidirectionele streaming en flow control” gratis?

Ja — de volledige tekst van “Bidirectionele streaming en flow control” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Programmeren van WebSockets en realtime-systemen wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Programmeren van WebSockets en realtime-systemen bevat in totaal 4 lessen.

Wat leer ik in “Bidirectionele streaming en flow control”?

Begrijp hoe u continue datastromen in beide richtingen beheert en basisprincipes van flow control implementeert. Je oefent met Programmeren van WebSockets en realtime-systemen door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Programmeren van WebSockets en realtime-systemen te beginnen?

Ervaring vooraf is niet nodig. Programmeren van WebSockets en realtime-systemen op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Bidirectionele streaming en flow control”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Programmeren van WebSockets en realtime-systemen?

Ja. Elke les over Programmeren van WebSockets en realtime-systemen bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Publish/subscribe-berichten implementeren
  2. Request-response via WebSockets
  3. Bidirectionele streaming en flow control
  4. Backpressure en batching van berichten
← Terug naar Programmeren van WebSockets en realtime-systemen