Maison >interface Web >js tutoriel >Diffusion WebSocket avec JavaScript et Bun

Diffusion WebSocket avec JavaScript et Bun

Susan Sarandon
Susan Sarandonoriginal
2024-12-09 01:29:11216parcourir

WebSocket broadcasting with JavaScript and Bun

La diffusion est l'une des fonctionnalités les plus puissantes des WebSockets, permettant aux serveurs d'envoyer des messages à plusieurs clients connectés simultanément. Contrairement à la communication point à point, où les messages sont échangés entre un seul client et le serveur, la diffusion permet à un seul message d'atteindre un groupe de clients. Cela le rend indispensable pour les applications en temps réel, collaboratives et interactives.


Pourquoi la radiodiffusion est importante

La diffusion est essentielle dans les scénarios dans lesquels plusieurs utilisateurs doivent rester synchronisés ou informés des mêmes mises à jour en temps réel. Par exemple :

  • Applications de chat de groupe : envoi d'un message à tous les participants d'un salon de discussion.
  • Outils collaboratifs : informer tous les utilisateurs des documents partagés ou des modifications de contenu.
  • Notifications en direct : diffusion des dernières nouvelles, des mises à jour boursières ou des résultats sportifs à plusieurs abonnés.
  • Jeux en ligne : synchronisation des états de jeu ou des actions de plusieurs joueurs.

Dans de tels cas, la diffusion garantit que tous les utilisateurs connectés restent synchronisés sans nécessiter d'appels de serveur individuels pour chaque client, ce qui serait autrement inefficace et sujet à la latence.


Deux approches de la diffusion

Lors de la mise en œuvre de la diffusion, il existe deux stratégies courantes à considérer :

  • Diffusion à tous les clients (y compris l'expéditeur)
  • Diffusion à tous les clients sauf l'expéditeur

Diffusion à tous les clients (y compris l'expéditeur)

Cette approche envoie le message à tous les clients connectés à un canal spécifique, y compris celui à l'origine du message.

Cette approche convient aux situations où chaque client, y compris l'expéditeur, a besoin de recevoir la diffusion, comme l'affichage d'un accusé de réception ou d'une mise à jour de son message dans une discussion de groupe.

Diffusion à tous les clients sauf l'expéditeur

Dans ce cas, le message est diffusé à tous les clients sauf celui qui l'a envoyé.

Cette approche est idéale pour les scénarios dans lesquels l'expéditeur n'a pas besoin de voir son propre message dans la diffusion, comme dans un jeu multijoueur dans lequel les actions doivent être partagées avec d'autres joueurs mais ne doivent pas être renvoyées à celui qui exécute l'action. .

Les deux méthodes ont des cas d'utilisation spécifiques et peuvent être facilement mises en œuvre avec des outils comme Bun, permettant aux développeurs de gérer efficacement la diffusion avec un minimum de code.


Cet article explique comment configurer la diffusion WebSocket à l'aide de Bun et démontre les deux approches de diffusion, vous aidant ainsi à créer des applications robustes en temps réel.

Le code pour diffuser avec WebSockets

Dans le premier article de cette série, WebSocket avec JavaScript et Bun, nous avons exploré la structure d'un serveur WebSocket qui répond aux messages envoyés par un client.

Cet article explorera les abonnements aux chaînes, un mécanisme qui permet de diffuser des messages à plusieurs clients.

Nous commencerons par présenter le code complet, puis le décomposerons pour explorer toutes les parties pertinentes en détail.

Créez le fichier Broadcast.ts :

console.log("? Hello via Bun! ?");
const server = Bun.serve({
  port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
  fetch(req, server) {
    const url = new URL(req.url);
    if (url.pathname === "/") return new Response(Bun.file("./index.html"));
    if (url.pathname === "/surprise") return new Response("?");

    if (url.pathname === "/chat") {
      if (server.upgrade(req)) {
        return; // do not return a Response
      }
      return new Response("Upgrade failed", { status: 400 });
    }

    return new Response("404!");
  },
  websocket: {
    message(ws, message) {
      console.log("✉️ A new Websocket Message is received: " + message);
      ws.send("✉️ I received a message from you:  " + message);
      ws.publish(
        "the-group-chat",
        `? Message from ${ws.remoteAddress}: ${message}`,
      );
    }, // a message is received
    open(ws) {
      console.log("? A new Websocket Connection");
      ws.subscribe("the-group-chat");
      ws.send("? Welcome baby");
      ws.publish("the-group-chat", "? A new friend is joining the Party");
    }, // a socket is opened
    close(ws, code, message) {
      console.log("⏹️ A Websocket Connection is CLOSED");
      const msg = `A Friend has left the chat`;
      ws.unsubscribe("the-group-chat");
      ws.publish("the-group-chat", msg);
    }, // a socket is closed
    drain(ws) {
      console.log("DRAIN EVENT");
    }, // the socket is ready to receive more data
  },
});
console.log(`? Server (HTTP and WebSocket) is launched ${server.url.origin}`);

setInterval(() => {
  const msg = "Hello from the Server, this is a periodic message!";
  server.publish("the-group-chat", msg);
  console.log(`Message sent to "the-group-chat": ${msg}`);
}, 5000); // 5000 ms = 5 seconds

vous pouvez l'exécuter via :

bun run broadcast.ts

Ce code introduit la diffusion, permettant au serveur d'envoyer des messages à tous les clients abonnés dans un canal spécifique. Il fait également la différence entre la diffusion à tous les clients (y compris l'expéditeur) ou l'exclusion de l'expéditeur. Voici une explication détaillée :


Initialisation du serveur

const server = Bun.serve({
  port: 8080,
  ...
});

L'initialisation est la même que celle de l'article précédent.
Le serveur écoute sur le port 8080 et, comme dans l'exemple précédent, il gère les requêtes HTTP et met à niveau les connexions WebSocket pour /chat.


Diffusion dans WebSockets

La diffusion permet d'envoyer un message à tous les clients abonnés à un canal spécifique, comme un chat de groupe.
Voici comment le code y parvient :


S'abonner à une chaîne (dans l'événement ouvert)

open(ws) {
  console.log("? A new Websocket Connection");
  ws.subscribe("the-group-chat");
  ws.send("? Welcome baby");
  ws.publish("the-group-chat", "? A new friend is joining the Party");
}
  • ws.subscribe(channel) : abonne le client au canal the-group-chat. Tous les clients de ce canal peuvent désormais recevoir des messages qui y sont diffusés.
  • ws.send(...) : le client est accueilli individuellement .
  • ws.publish(channel, message) : diffuse un message à tous les clients du canal.

Diffusion de messages (réponse/diffusion d'un message d'un client dans l'événement message)

message(ws, message) {
  console.log("✉️ A new Websocket Message is received: " + message);
  ws.send("✉️ I received a message from you:  " + message);
  ws.publish("the-group-chat", `? Message from ${ws.remoteAddress}: ${message}`);
}

Lorsqu'un message est reçu d'un client :

  • L'expéditeur reçoit un accusé de réception via ws.send(...).
  • Le message est diffusé à tous les clients (à l'exclusion de l'expéditeur) dans "the-group-chat" en utilisant ws.publish(...).

Remarque : L'expéditeur ne reçoit pas le message de diffusion car nous appelons la méthode de publication sur l'objet ws. Vous devez utiliser l'objet serveur pour inclure l'expéditeur.


Désabonnement et diffusion à la déconnexion (en cas de clôture)

close(ws, code, message) {
  console.log("⏹️ A Websocket Connection is CLOSED");
  const msg = `A Friend has left the chat`;
  ws.unsubscribe("the-group-chat");
  ws.publish("the-group-chat", msg);
}

Quand un client se déconnecte :

  • ws.unsubscribe(channel) : supprime le client de l'abonnement à la chaîne.
  • Un message est diffusé à tous les clients restants du canal, les informant de la déconnexion.

Messages périodiques du serveur à tous les clients

console.log("? Hello via Bun! ?");
const server = Bun.serve({
  port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
  fetch(req, server) {
    const url = new URL(req.url);
    if (url.pathname === "/") return new Response(Bun.file("./index.html"));
    if (url.pathname === "/surprise") return new Response("?");

    if (url.pathname === "/chat") {
      if (server.upgrade(req)) {
        return; // do not return a Response
      }
      return new Response("Upgrade failed", { status: 400 });
    }

    return new Response("404!");
  },
  websocket: {
    message(ws, message) {
      console.log("✉️ A new Websocket Message is received: " + message);
      ws.send("✉️ I received a message from you:  " + message);
      ws.publish(
        "the-group-chat",
        `? Message from ${ws.remoteAddress}: ${message}`,
      );
    }, // a message is received
    open(ws) {
      console.log("? A new Websocket Connection");
      ws.subscribe("the-group-chat");
      ws.send("? Welcome baby");
      ws.publish("the-group-chat", "? A new friend is joining the Party");
    }, // a socket is opened
    close(ws, code, message) {
      console.log("⏹️ A Websocket Connection is CLOSED");
      const msg = `A Friend has left the chat`;
      ws.unsubscribe("the-group-chat");
      ws.publish("the-group-chat", msg);
    }, // a socket is closed
    drain(ws) {
      console.log("DRAIN EVENT");
    }, // the socket is ready to receive more data
  },
});
console.log(`? Server (HTTP and WebSocket) is launched ${server.url.origin}`);

setInterval(() => {
  const msg = "Hello from the Server, this is a periodic message!";
  server.publish("the-group-chat", msg);
  console.log(`Message sent to "the-group-chat": ${msg}`);
}, 5000); // 5000 ms = 5 seconds

Toutes les 5 secondes, le serveur diffuse un message à tous les clients du canal "the-group-chat" en utilisant server.publish(...). Ici, nous utilisons l'objet serveur.


Méthodes clés

  • ws.subscribe(channel) : abonne le client WebSocket actuel à un canal de communication de groupe.
  • ws.publish(channel, message) : diffuse un message à tous les clients du canal spécifié (à l'exclusion de l'expéditeur).
  • server.publish(channel, message) : similaire à ws.publish, mais utilisé au niveau du serveur pour la diffusion à tous les clients abonnés (y compris l'expéditeur).
  • ws.unsubscribe(channel) : supprime le client actuel du canal.

Exemple de flux

  1. Un client se connecte à /chat, s'abonnant à "the-group-chat".
  2. Le client envoie un message au serveur :
    • Le message est renvoyé à l'expéditeur.
    • Le serveur diffuse le message à tous les autres clients du canal.
  3. Quand un client se déconnecte :
    • il est désabonné de la chaîne.
    • Le serveur informe les clients restants de la déconnexion.
  4. Toutes les 5 secondes, le serveur envoie un message de diffusion périodique à tous les clients.

Conclusion

Les WebSockets sont un outil puissant pour créer des applications Web interactives en temps réel. Contrairement à la communication HTTP traditionnelle, les WebSockets fournissent un canal bidirectionnel persistant qui permet l'échange de messages instantanés entre le serveur et les clients connectés. Cela les rend idéaux pour des scénarios tels que les chats en direct, les outils collaboratifs, les jeux ou toute application où une communication à faible latence est cruciale.

Dans cet article (et dans la série), nous avons exploré les bases de la configuration d'un serveur WebSocket à l'aide de Bun, de la gestion des connexions client et de la diffusion de messages aux clients abonnés. Nous avons également montré comment mettre en œuvre un système de discussion de groupe simple dans lequel les clients peuvent rejoindre un canal, envoyer des messages et recevoir des mises à jour d'autres clients et du serveur lui-même.

En tirant parti de la prise en charge WebSocket intégrée de Bun et de fonctionnalités telles que l'abonnement, la publication et le désabonnement, il devient remarquablement facile de gérer la communication en temps réel. Que vous envoyiez des mises à jour périodiques, diffusiez à tous les clients ou gériez des canaux spécifiques, les WebSockets offrent un moyen efficace et évolutif de répondre à ces exigences.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn