WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi · Oppitunti

Julkaisu–tilaus-viestinnän toteuttaminen

Suunnitelkaa ja rakentakaa WebSocketeilla pub/sub-järjestelmä aihekohtaista viestien jakelua varten.

Oppitunti 1/411 vaihetta

Julkaisu–tilaus-viestinnän toteuttaminen on ilmainen WebSockets- ja reaaliaikaisten järjestelmien ohjelmointi-oppitunti CoddyKitissä. Tämä on oppitunti 1/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.

Johdanto Pub/Sub-viestintään

Tervetuloa tutustumaan edistyneisiin WebSocket-malleihin! Tänään tarkastelemme julkaisu–tilaus-viestintää (Pub/Sub), joka on tehokas tapa jakaa reaaliaikaista dataa.

Kuvitelkaa digitaalinen sanomalehti, jossa saatte vain teitä kiinnostavien aiheiden artikkelit. Juuri tätä Pub/Sub tarkoittaa käytännössä!

Se sopii erinomaisesti esimerkiksi reaaliaikaisiin keskusteluhuoneisiin, sosiaalisen median syötteisiin, osakekursseihin ja kaikkiin sovelluksiin, jotka tarvitsevat dynaamisia aihekohtaisia päivityksiä.

Pub/Sub-järjestelmän keskeiset osat

Pub/Sub-järjestelmässä on muutama keskeinen komponentti:

  • Julkaisijat: Nämä ovat viestejä lähettäviä tahoja. Ne eivät tiedä, kuka viestit vastaanottaa.
  • Tilaajat: Nämä ovat viestejä vastaanottavia tahoja. Ne ilmaisevat kiinnostuksensa tiettyihin aiheisiin.
  • Aihepiirit: Nämä ovat viestien luokkia tai kanavia. Tilaajat 'virittäytyvät' seuraamiinsa aihepiireihin.
  • Välittäjä: Tämä on keskitetty komponentti (WebSocket-palvelimemme), joka vastaanottaa viestejä julkaisijoilta ja välittää ne asiaankuuluville tilaajille.

WebSocket-palvelin välittäjänä

WebSocket Pub/Sub -järjestelmässämme WebSocket-palvelin toimii välittäjänä.

Sen vastuulla on:

  • Asiakkaiden yhteyksien vastaanottaminen.
  • Luettelon hallinta siitä, mitkä asiakkaat ovat tilanneet mitkäkin aiheet.
  • Viestien vastaanottaminen 'julkaisija'-asiakkailta.
  • Viestien jakaminen kaikille kyseisen aiheen 'tilaaja'-asiakkaille.

Käytämme palvelimella Map-tietorakennetta tilausten tallentamiseen. Siinä kukin aiheen nimi yhdistetään yhdistettyjen WebSocket-asiakasolioiden Set-joukkoon.

Viestimuotojen suunnittelu

Jotta Pub/Sub-järjestelmämme toimisi, asiakkailla ja palvelimella on oltava selkeä viestintätapa. Käytämme yksinkertaisia JSON-viestejä.

1. Tilausviesti (asiakkaalta palvelimelle):

{ "action": "subscribe", "topic": "chat:general" }

2. Julkaisuviesti (asiakkaalta palvelimelle):

{ "action": "publish", "topic": "news", "payload": "Breaking: New feature released!" }

3. Toimitettu viesti (palvelimelta asiakkaalle):

{ "type": "message", "topic": "chat:general", "payload": "Hello everyone!" }

Palvelin: Pub/Sub-peruslogiikka

Tässä on täydellinen Node.js-WebSocket-palvelin, joka toteuttaa Pub/Sub-järjestelmän perusominaisuudet. Se käsittelee sekä subscribe- että publish-viestejä.

Suorittakaa tämä koodi (node server.js komennon npm install ws jälkeen) ja yhdistäkää sitten selaimenne asiakkaat palvelimeen testaamista varten!

const { WebSocketServer } = require('ws');
const wss = new WebSocketServer({ port: 8080 });

// Stores active subscriptions: Map<topic, Set<WebSocket>>
const subscriptions = new Map();

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

  ws.on('message', message => {
    try {
      const data = JSON.parse(message.toString());
      const { action, topic, payload } = data;

      if (action === 'subscribe' && topic) {
        if (!subscriptions.has(topic)) {
          subscriptions.set(topic, new Set());
        }
        subscriptions.get(topic).add(ws);
        ws.send(JSON.stringify({ status: 'subscribed', topic }));
        console.log(`Client subscribed to '${topic}'.`);
      } else if (action === 'publish' && topic && payload) {
        const topicSubscribers = subscriptions.get(topic);
        if (topicSubscribers) {
          topicSubscribers.forEach(subscriber => {
            if (subscriber.readyState === ws.OPEN) {
              subscriber.send(JSON.stringify({ type: 'message', topic, payload }));
            }
          });
          console.log(`Published to '${topic}': ${payload}.`);
        } else {
          ws.send(JSON.stringify({ error: `No subscribers for '${topic}'.` }));
        }
      } else {
        ws.send(JSON.stringify({ error: 'Invalid message.' }));
      }
    } catch (e) {
      console.error('Message error:', e.message);
      ws.send(JSON.stringify({ error: 'JSON parse error.' }));
    }
  });

  // Connection close and error handling in the next scene
});

console.log('Pub/Sub server running on ws://localhost:8080');

Palvelin: yhteyden elinkaari

Yhteyden elinkaaren hallinta on olennaista vankassa Pub/Sub-palvelimessa. Palvelimen on käsiteltävä asiakkaiden yhteyksien katkeamiset hallitusti.

  • ws.on('close')-tapahtuma suoritetaan, kun asiakkaan yhteys katkeaa.
  • Tämän käsittelijän sisällä käymme läpi kaikki aiheet ja poistamme yhteyden katkaisseen asiakkaan kaikista tilausluetteloista, joissa se oli mukana.
  • Siivoamme myös aiheet, jotka tyhjenevät asiakkaan poistuttua.
  • ws.on('error')-käsittelijä sieppaa viestinnän virheet.

Asiakas: yhteyden muodostaminen ja tilaaminen

Tarkastellaan nyt asiakaspuolta, joka toimii yleensä verkkoselaimessa. Käytämme natiivia WebSocket-APIa.

Tämä koodikatkelma muodostaa yhteyden palvelimeemme ja lähettää subscribe-viestin tietystä aiheesta.

Muistakaa avata tämä HTML-tiedosto selaimessa ja varmistaa, että Node.js-palvelin on käynnissä!

<!-- index.html -->
<!DOCTYPE html>
<html>
<head><title>Pub/Sub Client</title></head>
<body>
  <h1>Pub/Sub Client</h1>
  <p>Status: <span id="status">Disconnected</span></p>
  <ul id="messages"></ul>

  <script>
    const ws = new WebSocket('ws://localhost:8080');
    const statusElem = document.getElementById('status');
    const messagesElem = document.getElementById('messages');

    ws.onopen = () => {
      statusElem.textContent = 'Connected';
      console.log('Connected to server');
      // Subscribe to a topic
      ws.send(JSON.stringify({ action: 'subscribe', topic: 'chat:general' }));
      ws.send(JSON.stringify({ action: 'subscribe', topic: 'news' }));
    };

    ws.onclose = () => {
      statusElem.textContent = 'Disconnected';
      console.log('Disconnected from server');
    };

    ws.onerror = (error) => {
      console.error('WebSocket Error:', error);
    };

    // Message handling in the next scene
  </script>
</body>
</html>

Asiakas: vastaanottaminen ja näyttäminen

Tilauksen tekemisen jälkeen asiakkaan on kuunneltava palvelimelta saapuvia viestejä. Tämä tapahtuu ws.onmessage-tapahtuman kautta.

Kun viesti saapuu, jäsennämme sen JSON-sisällön ja voimme näyttää sen käyttäjälle, esimerkiksi suodattamalla tai muotoilemalla sitä viestin topic-arvon perusteella.

Avatkaa useita selaimen välilehtiä, tilatkaa sama aihe ja julkaiskaa sitten viesti yhdeltä välilehdeltä (esimerkiksi konsolin kautta), jotta näette sen muissa välilehdissä!

<!-- index.html (continued script part) -->
    // ... (ws.onopen, ws.onclose, ws.onerror from previous scene)

    ws.onmessage = event => {
      const data = JSON.parse(event.data);
      console.log('Received:', data);

      if (data.type === 'message') {
        const listItem = document.createElement('li');
        listItem.textContent = `[${data.topic}] ${data.payload}`;
        messagesElem.appendChild(listItem);
      } else if (data.status === 'subscribed') {
        const listItem = document.createElement('li');
        listItem.textContent = `Successfully subscribed to '${data.topic}'.`;
        messagesElem.appendChild(listItem);
      } else if (data.error) {
        console.error('Server error:', data.error);
        const listItem = document.createElement('li');
        listItem.style.color = 'red';
        listItem.textContent = `Error: ${data.error}`; 
        messagesElem.appendChild(listItem);
      }
    };

    // Example of how a client could publish a message (e.g., via a button click)
    // ws.send(JSON.stringify({ action: 'publish', topic: 'chat:general', payload: 'Hello from client!' }));
  </script>
</body>
</html>

Edistyneet Pub/Sub-mallit

Vaikka perusmuotoinen Pub/Sub-järjestelmämme toimii, tosielämän sovellukset tarvitsevat usein enemmän:

  • Tilauksen peruuttaminen: Asiakkaan pitäisi voida lopettaa aiheen viestien vastaanottaminen. Tämä edellyttäisi uutta viestin toimintoa (esimerkiksi { "action": "unsubscribe", "topic": "news" }) sekä palvelinpuolen logiikkaa, joka poistaa asiakkaan aiheen tilaajajoukosta.
  • Aihehierarkiat: Tilausten salliminen malleille, kuten news.*, jotta tilaaja vastaanottaa kaikki uutisten ala-aiheet.
  • Viestien pysyvä tallennus: Viestien tallentaminen niin, että uudet tilaajat voivat vastaanottaa aiemmat viestit (esimerkiksi keskusteluhistorian).

Pikakysymys

Tarkastelkaa juuri rakentamaamme Pub/Sub-järjestelmää. Mikä komponentti on ensisijaisesti vastuussa siitä, mitkä tilaajat vastaanottavat tiettyyn aiheeseen julkaistun viestin?

Kertaus ja seuraavat askeleet

Onnittelut! Olette oppineet suunnittelemaan ja toteuttamaan WebSocketien avulla perustason julkaisu–tilaus-viestintäjärjestelmän.

Käsittelimme keskeiset komponentit (julkaisija, tilaaja, aihepiiri ja välittäjä), määrittelimme viestimuodot sekä rakensimme palvelinpuolen välittäjälogiikan ja asiakaspuolen tilaus- ja vastaanottotoiminnot.

Pub/Sub on monien reaaliaikaisten sovellusten perustavanlaatuinen malli. Kokeilkaa tilauksen peruuttamisen, monimutkaisemman aiheiden hallinnan tai ulkoisten viestijonojen integrointia suurempia käyttömääriä varten.

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 ”Julkaisu–tilaus-viestinnän toteuttaminen” ilmainen?

Kyllä – oppitunnin ”Julkaisu–tilaus-viestinnän toteuttaminen” 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 ”Julkaisu–tilaus-viestinnän toteuttaminen”?

Suunnitelkaa ja rakentakaa WebSocketeilla pub/sub-järjestelmä aihekohtaista viestien jakelua varten. 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 1/4.

Kuinka kauan ”Julkaisu–tilaus-viestinnän toteuttaminen”-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