WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi · Oppitunti

Kaksisuuntainen suoratoisto ja vuonhallinta

Ymmärrä, miten jatkuvia tietovirtoja hallitaan molempiin suuntiin ja miten toteutetaan perusmuotoinen vuonhallinta.

Oppitunti 3/411 vaihetta

Kaksisuuntainen suoratoisto ja vuonhallinta on ilmainen WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-kurssilla on yhteensä 4 oppituntia.

Yksinkertaisia viestejä pidemmälle

Tähän asti olemme tarkastelleet WebSocketien käyttöä lähinnä yksittäisten viestien lähettämiseen edestakaisin. Mutta entä jos tarvitsette jatkuvan datavirran siirtämistä?

Tässä kohtaa mukaan tulee kaksisuuntainen suoratoisto. Siinä data virtaa jatkuvasti ja samanaikaisesti molempiin suuntiin sen sijaan, että kyse olisi vain toisistaan irrallisista viesteistä.

Miksi kaksisuuntainen suoratoisto on tärkeää

Ajatelkaa esimerkiksi seuraavia tilanteita:

  • Reaaliaikainen ääni ja video: Reaaliaikaisten mediavirtojen lähettäminen ja vastaanottaminen.
  • Suurten tiedostojen siirrot: Suurten tiedostojen lataaminen palvelimelle tai palvelimelta osissa.
  • Reaaliaikainen analytiikka: Suurten datamäärien jatkuvat päivitykset koontinäyttöihin.

Näissä tilanteissa jatkuva datavirta on tehokkaampi kuin monet pienet ja erilliset datapisarat.

Datavirran hallinnan haaste

Mitä tapahtuu, jos toinen osapuoli lähettää dataa paljon nopeammin kuin toinen pystyy käsittelemään sitä? Kuvitelkaa paloletku kaatamassa vettä pieneen kuppiin.

Vastaanottimen väliaikainen tallennustila eli puskuri täyttyy nopeasti. Se voi johtaa seuraaviin ongelmiin:

  • Datan häviäminen
  • Järjestelmän hidastuminen
  • Muistin loppuminen

Tämä on jatkuvan datavirran kannalta kriittinen ongelma.

Vuonhallinnan esittely

Jotta vastaanotin ei kuormitu liikaa, käytämme vuonhallintaa. Se on mekanismi, joka hallitsee datan siirtonopeutta lähettäjän ja vastaanottimen välillä.

Sen päätavoitteena on varmistaa, ettei lähettäjä lähetä dataa nopeammin kuin vastaanotin pystyy käsittelemään sitä. Näin tiedonsiirto pysyy sujuvana ja luotettavana.

Vuonhallinnan keskeiset käsitteet

Vuonhallinta perustuu muutamaan keskeiseen ajatukseen:

  • Puskurointi: Lähetetyn mutta vastaanottajan vielä käsittelemättömän datan väliaikainen tallennus.
  • Takapaine: Vastaanottimen lähettäjälle lähettämä signaali, joka ilmaisee tarpeen hidastaa tai keskeyttää lähetys.
  • Tauotus ja jatkaminen: Eksplisiittiset komennot tai implisiittiset toimintatavat, joilla datavirta pysäytetään ja käynnistetään uudelleen.

Ajatelkaa sitä datavirran liikennevalona.

WebSocketien puskurointi Node.js:ssä

Kun käytätte Node.js:ssä ws.send(data)-kutsua, ws-kirjasto hallitsee lähtevien viestien sisäistä puskuria.

ws.send()-metodi palauttaa boolean-arvon:

  • true: Data lähetettiin heti tai puskuroitiin onnistuneesti.
  • false: Sisäinen puskuri on täynnä. Lähetys kannattaa keskeyttää.

Voitte tarkistaa myös arvon ws.bufferedAmount, joka kertoo lähtevän puskurin tämänhetkisen koon tavuina.

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

Takapaine palvelimella (osa 1)

Vuonhallinnan toteuttamiseksi palvelimen on reagoitava, kun sen lähtevä puskuri täyttyy. Jos ws.send() palauttaa arvon false, datan lähetys on lopetettava, kunnes puskuri tyhjenee.

Näin palvelin ei kuluta liikaa muistia eikä kuormita asiakkaan yhteyttä liikaa.

Tauottamisen perusidea on seuraava:

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

Takapaine palvelimella (osa 2)

Kun puskurissa on jälleen riittävästi tilaa uudelle datalle, ws-kirjasto lähettää 'drain'-tapahtuman. Se on merkki siitä, että lähettämistä voi jatkaa!

ws.send()-kutsun palautusarvon ja 'drain'-tapahtuman yhdistäminen muodostaa vankan palvelinpuolen vuonhallinnan.

Kokeilkaa tämän täydellisen esimerkin suorittamista. Näette viestit ”Buffer full!” ja ”Buffer drained!”, kun vuonhallinta aktivoituu.

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

Vuonhallinta asiakkaalla

Palvelinpuolen esimerkki keskittyy lähtevään dataan, mutta myös asiakkaiden on hallittava saapuvia virtoja ja mahdollisesti omia lähteviä virtojaan.

Asiakaspuolella (selaimen JavaScript):

  • Vastaanotettaessa saapuvia viestejä voidaan puskuroida, jos niiden käsittely on hidasta.
  • Lähetettäessä suuria datamääriä (esimerkiksi tiedostoja palvelimelle) data lähetetään osissa, ja asiakaspuolen takapaineen toteuttamiseen saatetaan tarvita palvelimen kuittauksia tai eksplisiittisiä ”pause”-signaaleja.

Perusperiaatteet pysyvät samoina: dataa ei pidä lähettää nopeammin kuin vastaanottaja pystyy käsittelemään sitä.

Pikatesti: vuonhallinnan logiikka

Ajatellaan Node.js-WebSocket-palvelinta, joka yrittää lähettää asiakkaalle suuren määrän dataa. Mitkä seuraavista palvelinpuolen vuonhallinnan toteuttamista koskevista väitteistä PITÄVÄT PAIKKANSA?

Kertaus: reaaliaikaisten virtojen hallinta

Tässä oppitunnissa tarkastelimme kaksisuuntaista suoratoistoa ja WebSocketien kannalta keskeistä vuonhallinnan käsitettä.

  • Kaksisuuntainen suoratoisto mahdollistaa jatkuvan ja samanaikaisen datavirran, joten se sopii esimerkiksi suoraan videolähetykseen ja suurten datamäärien siirtämiseen.
  • Vuonhallinta, jossa käytetään esimerkiksi puskurointia, takapainetta ja 'drain'-tapahtumaa, estää sekä lähettäjän että vastaanottimen ylikuormittumisen.
  • Asianmukainen vuonhallinta on välttämätöntä vankkojen, suorituskykyisten ja luotettavien reaaliaikaisten sovellusten rakentamisessa.

Pidättehän nämä periaatteet mielessä, kun rakennatte seuraavaa suoratoistoon perustuvaa WebSocket-sovellustanne!

Aloita maksutta

Opi WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
12
Oppitunnit
47

Usein kysytyt kysymykset

Onko oppitunti ”Kaksisuuntainen suoratoisto ja vuonhallinta” ilmainen?

Kyllä – oppitunnin ”Kaksisuuntainen suoratoisto ja vuonhallinta” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-kurssin, päivitä CoddyKit PROhon. WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Kaksisuuntainen suoratoisto ja vuonhallinta”?

Ymmärrä, miten jatkuvia tietovirtoja hallitaan molempiin suuntiin ja miten toteutetaan perusmuotoinen vuonhallinta. Harjoittelet WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Kaksisuuntainen suoratoisto ja vuonhallinta”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-oppitunnilla?

Kyllä. Jokainen WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Julkaisu–tilaus-viestinnän toteuttaminen
  2. Pyyntö–vastaus WebSocketeilla
  3. Kaksisuuntainen suoratoisto ja vuonhallinta
  4. Backpressure ja viestien ryhmittely
← Takaisin: WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi