Maison> interface Web> js tutoriel> le corps du texte

Créez et déployez une application de chat à l'aide de Socket.io et Redis.

王林
Libérer: 2024-08-26 21:40:32
original
371 Les gens l'ont consulté

Build and deploy a chat application using Socket.io and Redis.

Dans ce tutoriel, nous allons créer une application de chat à l'aide de sockets Web. Les sockets Web sont vraiment utiles lorsque vous souhaitez créer des applications nécessitant un transfert de données en temps réel.

À la fin de ce didacticiel, vous serez en mesure de configurer votre propre serveur socket, d'envoyer et de recevoir des messages en temps réel, de stocker des données dans Redis et de déployer votre application lors du rendu et de l'exécution de Google Cloud.

Qu’allons-nous construire ?

Nous allons créer une application de chat. Pour faire court, nous allons uniquement configurer le serveur. Vous pouvez utiliser votre propre framework front-end et suivre.

Dans cette application de chat, il y aura des salles et les utilisateurs pourront rejoindre une salle et commencer à discuter. Pour que tout reste simple, nous supposerons que les noms d’utilisateur ne sont pas uniques. Cependant chaque salle ne peut avoir qu'un seul utilisateur avec un nom d'utilisateur spécifique.

Configurez un serveur de socket.

Nous devons d'abord installer les dépendances requises.

npm i express cors socket.io -D @types/node
Copier après la connexion

Nous utiliserons le module http pour configurer notre serveur socket. Puisque notre application fonctionnera dans le terminal, nous devrons autoriser toutes les origines.

import express from "express"; import cors from "cors" import { Server } from "socket.io"; import { createServer } from "http" const app = express(); const server = createServer(app); // create a socket server. const io = new Server(server, { cors: { origin: "*", credentials: true, } }); // listen to connections errors io.engine.on("connection_error", console.log) app.use(cors()) const PORT = 3000; server.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Copier après la connexion

Configuration de Redis.

Nous utiliserons Redis pour stocker nos messages ainsi que les informations sur la salle et les utilisateurs. Vous pouvez utiliser Upstash Redis (gratuit). Créez une nouvelle instance Redis dans votre tableau de bord Upstash. Après la création, vous recevrez une URL Redis que vous pourrez utiliser pour vous connecter à votre instance Redis.

Installez n'importe quel client Redis de votre choix. J'utiliserai ioredis.

npm i ioredis
Copier après la connexion

Ensuite, nous allons initialiser notre client Redis et le connecter à notre serveur Redis en utilisant l'URL de connexion que nous avons obtenue.

/** /src/index.ts */ import { Redis } from "ioredis" if (!process.env.REDIS_URL) throw new Error("REDIS_URL env variable is not set"); const redis = new Redis(process.env.REDIS_URL); // listen to connection events. redis.on("connect", () => console.log("Redis connected")) redis.on("error", console.log)
Copier après la connexion

Gestion des événements.

Les utilisateurs peuvent créer des salles ou rejoindre des salles existantes. Les chambres sont identifiées par des identifiants de pièce uniques. Chaque membre possède un nom d'utilisateur qui est unique à l'intérieur d'une salle, et non globalement.

Nous pouvons garder une trace de toutes les salles actives sur notre serveur, en stockant leurs identifiants de salle dans un ensemble Redis.

Pour notre propos, les noms d'utilisateur ne sont uniques qu'à l'intérieur d'une pièce. Nous les stockons donc dans un ensemble avec l’identifiant de la pièce. Cela garantit que la combinaison de l'identifiant de la salle et de l'identifiant du membre est unique à l'échelle mondiale.

Nous pouvons configurer un événement socket pour créer une salle. Lorsque nous créons une salle, nous ajoutons également le membre qui a demandé sa création dans la salle.

io.on("connection", () => { // ... socket.on("create:room", async (message) => { console.log("create:room", message) const doesRoomExist = await redis.sismember("rooms", message.roomId) if (doesRoomExist === 1) return socket.emit("error", { message: "Room already exist."}) const roomStatus = await redis.sadd("rooms", message.roomId) const memStatus = await redis.sadd("members", message.roomId + "::" + message.username) if (roomStatus === 0 || memStatus === 0) return socket.emit("error", { message: "Room creation failed." }) socket.join(message.roomId) io.sockets.in(message.roomId).emit("create:room:success", message) io.sockets.in(message.roomId).emit("add:member:success", message) }) }
Copier après la connexion

Pour ajouter un nouveau membre dans une salle existante, nous devons d'abord vérifier si le membre existe déjà dans cette salle.

io.on("connection", () => { // ... socket.on("add:member", async (message) => { console.log("add:member", message) const doesRoomExist = await redis.sismember("rooms", message.roomId) if (doesRoomExist === 0) return socket.emit("error", { message: "Room does not exist." }) const doesMemExist = await redis.sismember("members", message.roomId + "::" + message.username) if (doesMemExist === 1) return socket.emit("error", { message: "Username already exists, please choose another username." }) const memStatus = await redis.sadd("members", message.roomId + "::" + message.username) if (memStatus === 0) return socket.emit("error", { message: "User creation failed." }) socket.join(message.roomId) io.sockets.in(message.roomId).emit("add:member:success", message) }) socket.on("remove:member", async (message) => { console.log("remove:member", message) const doesRoomExist = await redis.sismember("rooms", message.roomId) if (doesRoomExist === 0) return socket.emit("error", { message: "Room does not exist." }) await redis.srem("members", message.roomId + "::" + message.username) socket.leave(message.roomId) io.sockets.in(message.roomId).emit("remove:member:success", message) }) }
Copier après la connexion

Enfin, nous créons l'événement de chat.

io.on("connection", () => { socket.on("create:chat", (message) => { console.log("create:chat", message) redis.lpush("chat::" + message.roomId, message.username + "::" + message.message) io.sockets.in(message.roomId).emit("create:chat:success", message) }) }
Copier après la connexion

Déploiement.

Le serveur Socket nécessite des connexions persistantes, il ne fonctionnera pas dans des environnements sans serveur. Vous ne pouvez donc pas déployer votre serveur socket dans vercel.

Vous pouvez le déployer dans de nombreux endroits comme Render, fly.io ou Google Cloud Run.

Rendre

Déploiement sur rendu simple. Si vous disposez d'un fichier docker, il construira automatiquement votre projet à partir de ce fichier docker. Le rendu a un niveau gratuit, mais gardez à l'esprit qu'il y aura un démarrage à froid dans le niveau gratuit.

Voici mon fichier docker.

# syntax=docker/dockerfile:1 ARG NODE_VERSION=20.13.1 ARG PNPM_VERSION=9.4.0 FROM node:${NODE_VERSION}-bookworm AS base ## set shell to bash SHELL [ "/usr/bin/bash", "-c" ] WORKDIR /usr/src/app ## install pnpm. RUN --mount=type=cache,target=/root/.npm \ npm install -g pnpm@${PNPM_VERSION} # ------------ FROM base AS deps # Download dependencies as a separate step to take advantage of Docker's caching. # Leverage a cache mount to /root/.local/share/pnpm/store to speed up subsequent builds. # Leverage bind mounts to package.json and pnpm-lock.yaml to avoid having to copy them # into this layer. RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ --mount=type=cache,target=/root/.local/share/pnpm/store \ pnpm install --prod --frozen-lockfile # ----------- FROM deps AS build ## downloading dev dependencies. RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ --mount=type=cache,target=/root/.local/share/pnpm/store \ pnpm install --frozen-lockfile COPY . . RUN pnpm run build # ------------- FROM base AS final ENV NODE_ENV=production USER node COPY package.json . # Copy the production dependencies from the deps stage and also # the built application from the build stage into the image. COPY --from=deps /usr/src/app/node_modules ./node_modules COPY --from=build /usr/src/app/dist ./dist EXPOSE 3000 ENTRYPOINT [ "pnpm" ] CMD ["run", "start"]
Copier après la connexion

Google Cloud Exécuter

Si vous souhaitez une alternative gratuite pour effectuer le rendu et éviter les démarrages à froid, vous devez utiliser Google Cloud Run. Les étapes de déploiement sur Cloud Run dépassent le cadre de cet article, mais voici une courte liste de choses que vous devez faire.

  1. Créez votre image Docker à partir du fichier Docker fourni ci-dessous.

  2. Créez un référentiel d'artefacts à l'aide du service Google Artifact Registry.

  3. Renommez votre image Docker au format -docker.pkg.dev/ / :

  4. Poussez votre image vers votre référentiel d'artefacts.

  5. Déployez l'image sur Google Cloud Run. Assurez-vous de définir le nombre minimum d'instances actives sur une, pour éviter les démarrages à froid.

C'est tout pour ce tutoriel.

Merci d'avoir lu ❣️

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!

source:dev.to
Déclaration de ce site Web
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
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!