Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Note
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 10 de cet article.
Warning
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 10 de cet article.
Ce tutoriel montre comment utiliser Webpack dans une application web ASP.NET Core SignalR pour regrouper et générer un client écrit en TypeScript. Webpack permet aux développeurs de regrouper et générer les ressources côté client d’une application web.
Dans ce tutoriel, vous allez apprendre à :
- Créer une application ASP.NET Core SignalR
- Configurer le serveur SignalR
- Configurer un pipeline de build à l’aide de Webpack
- Configurer le client TypeScript SignalR
- Activer la communication entre le client et le serveur
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Prerequisites
La dernière version de Visual Studio avec la charge de travail de développement ASP.NET et web .
Créer l’application web ASP.NET Core
Par défaut, Visual Studio utilise la version de npm qu’il trouve dans son répertoire d’installation. Pour configurer Visual Studio pour rechercher npm dans la variable d’environnement PATH :
Lancez la dernière version de Visual Studio. Dans la fenêtre de démarrage, sélectionnez Continuer sans code.
Accédez à Outils>Options>Projets et solutions>Gestion des packages web>Outils web externes.
Sélectionnez l’entrée
$(PATH)dans la liste. Sélectionnez la flèche vers le haut pour déplacer l’entrée à la deuxième position de la liste, puis sélectionnez OK :
Pour créer une application web ASP.NET Core :
- Utilisez l’option de menu Fichier>Nouveau>Projet/Solution....
- Dans la boîte de dialogue Créer un nouveau projet, sélectionnez le modèle ASP.NET Core Empty. Ensuite, sélectionnez Suivant.
- Dans la boîte de dialogue Configurer votre nouveau projet, entrez
SignalRWebpackpour nom du projet. Cliquez sur Suivant. - Dans la boîte de dialogue Informations supplémentaires , sélectionnez .NET 10.0 (Support à long terme) dans la liste déroulante Framework . Cliquez sur Créer.
Ajoutez le package NuGet Microsoft.TypeScript.MSBuild au projet :
- Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud du projet, puis sélectionnez Gérer les packages NuGet....
- Sous l’onglet Parcourir, recherchez
Microsoft.TypeScript.MSBuild, puis cliquez sur Installer à droite pour installer le package. - Dans la boîte de dialogue Aperçu des modifications , sélectionnez Appliquer.
- Dans la boîte de dialogue Acceptation de la licence, sélectionnez J’accepte.
Visual Studio ajoute le package NuGet sous le nœud Dépendances dans Explorateur de solutions, ce qui permet la compilation TypeScript dans le projet.
Configurer le serveur
Dans cette section, vous allez configurer l’application web ASP.NET Core pour envoyer et recevoir des messages SignalR.
Dans
Program.cs, appelez AddSignalR :var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Là encore, dans
Program.cs, appelez UseDefaultFiles et UseStaticFiles :var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Le code précédent permet au serveur de localiser et de servir le fichier
index.html. Le fichier est servi si l’utilisateur entre son URL complète ou l’URL racine de l’application web.Créez un répertoire nommé
Hubsdans la racine du projet,SignalRWebpack/, pour la classe hub SignalR.Créez un fichier,
Hubs/ChatHub.cs, avec le code suivant :using Microsoft.AspNetCore.SignalR; namespace SignalRWebpack.Hubs; public class ChatHub : Hub { public async Task NewMessage(long username, string message) => await Clients.All.SendAsync("messageReceived", username, message); }Le code précédent diffuse les messages reçus à tous les utilisateurs connectés, une fois que le serveur les reçoit. Vous n’avez pas besoin d’avoir recours à une méthode générique
onpour recevoir tous les messages. Une méthode nommée après le nom du message est suffisante.Dans cet exemple :
- Le client TypeScript envoie un message identifié comme
newMessage. - La méthode C#
NewMessageattend les données envoyées par le client. - Un appel est effectué pour SendAsync sur Clients.All.
- Les messages reçus sont envoyés à tous les clients connectés au hub.
- Le client TypeScript envoie un message identifié comme
Ajoutez l’instruction
usingsuivante en haut deProgram.cspour résoudre la référenceChatHub:using SignalRWebpack.Hubs;Dans
Program.cs, mappez l’itinéraire/hubau hubChatHub. Remplacez le code qui afficheHello World!par le code suivant :app.MapHub<ChatHub>("/hub");
Configurer le client
Dans cette section, vous allez créer un projet Node.js pour convertir TypeScript en ressources JavaScript et regrouper des ressources côté client, notamment HTML et CSS, à l’aide de Webpack.
Exécutez la commande suivante dans la racine du projet pour créer un fichier
package.json:npm init -yAjoutez la propriété mise en surbrillance au fichier
package.jsonet enregistrez les modifications apportées au fichier :{ "name": "signalrwebpack", "version": "1.0.0", "private": true, "description": "", "main": "index.js", "scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" }, "keywords": [], "author": "", "license": "ISC", "type": "commonjs", "devDependencies": { "clean-webpack-plugin": "4.0.0", "css-loader": "7.1.3", "html-webpack-plugin": "5.6.6", "mini-css-extract-plugin": "2.10.0", "ts-loader": "9.5.4", "typescript": "5.9.3", "webpack": "5.104.1", "webpack-cli": "6.0.1" }, "dependencies": { "@microsoft/signalr": "^10.0.0", "@types/node": "^25.0.10" } }La définition de la propriété
privatesurtrueempêche les avertissements d’installation de package à l’étape suivante.Installez les packages npm nécessaires. À partir de la racine du projet, exécutez la commande suivante :
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliL’option
-Edésactive le comportement par défaut de npm qui consiste à écrire des opérateurs de plage de versionnage sémantique danspackage.json. Par exemple,"webpack": "5.76.1"peut être utilisé à la place de"webpack": "^5.76.1". Cette option empêche les mises à niveau involontaires vers des versions de package plus récentes.Pour plus d’informations, consultez la documentation npm-install.
Remplacez la propriété
scriptsdu fichierpackage.jsonpar le code suivant :"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Les scripts suivants sont définis :
-
build: Regroupe les ressources côté client en mode de développement et surveille les changements de fichier. L’observateur de fichiers entraîne la régénération du paquet chaque fois qu’un fichier de projet change. L'optionmodedésactive les optimisations de production, telles que le tree shaking et la minification. utilisezbuilduniquement dans le développement. -
release: Regroupe les ressources côté client en mode de production. -
publish: Exécute le scriptreleasepour regrouper les ressources côté client en mode de production. La commande appelle la commande publish de CLI .NET pour publier l’application.
-
Créez un fichier nommé
webpack.config.jsà la racine du projet avec le code suivant :const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "wwwroot"), filename: "[name].[chunkhash].js", publicPath: "/", }, resolve: { extensions: [".js", ".ts"], }, module: { rules: [ { test: /\.ts$/, use: "ts-loader", }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"], }, ], }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", }), new MiniCssExtractPlugin({ filename: "css/[name].[chunkhash].css", }), ], };Le fichier précédent configure le processus de compilation Webpack :
- La propriété
outputremplace la valeur par défaut dedist. Le paquet est plutôt émis dans le répertoirewwwroot. - Le tableau
resolve.extensionsinclut.jspour importer le code JavaScript du client SignalR.
- La propriété
Créez un nouveau répertoire nommé
srcà la racine du projet,SignalRWebpack/, pour le code client.Copiez le répertoire
srcet son contenu de l'exemple de projet vers la racine du projet. Le répertoiresrccontient les fichiers suivants :index.html, qui définit le balisage réutilisable de la page d’accueil :<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>ASP.NET Core SignalR with TypeScript and Webpack</title> </head> <body> <div id="divMessages" class="messages"></div> <div class="input-zone"> <label id="lblMessage" for="tbMessage">Message:</label> <input id="tbMessage" class="input-zone-input" type="text" /> <button id="btnSend">Send</button> </div> </body> </html>css/main.css, qui fournit des styles CSS pour la page d’accueil :*, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; } .input-zone { align-items: center; display: flex; flex-direction: row; margin: 10px; } .input-zone-input { flex: 1; margin-right: 10px; } .message-author { font-weight: bold; } .messages { border: 1px solid #000; margin: 10px; max-height: 300px; min-height: 300px; overflow-y: auto; padding: 5px; }tsconfig.json, qui configure le compilateur TypeScript pour produire du JavaScript compatible ECMAScript 5 :{ "compilerOptions": { "target": "es5" } }index.ts:import * as signalR from "@microsoft/signalr"; import "./css/main.css"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { const m = document.createElement("div"); const author = document.createElement("div"); author.className = "message-author"; author.textContent = username; const content = document.createElement("div"); content.textContent = message; m.append(author, content); divMessages.appendChild(m); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch((err) => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.key === "Enter") { send(); } }); btnSend.addEventListener("click", send); function send() { connection.send("newMessage", username, tbMessage.value) .then(() => (tbMessage.value = "")); }Le code précédent récupère les références aux éléments DOM et attache deux gestionnaires d’événements :
-
keyup: se déclenche lorsque l’utilisateur tape dans la zone de textetbMessageet appelle la fonctionsendlorsque l’utilisateur appuie sur la touche Entrée. -
click: se déclenche lorsque l’utilisateur sélectionne le bouton Envoyer et la fonctionsendest appelée.
La classe
HubConnectionBuildercrée un générateur pour configurer la connexion de serveur. La fonctionwithUrlconfigure l’URL du hub.SignalR permet l’échange de messages entre un client et un serveur. Chaque message a un nom spécifique. Par exemple, les messages portant le nom
messageReceivedpeuvent exécuter la logique responsable de l’affichage du nouveau message dans la zone de messages. L’écoute d’un message spécifique peut être effectuée au moyen de la fonctionon. N’importe quel nombre de noms de messages peuvent être écoutés. Vous pouvez aussi passer des paramètres au message, comme le nom de l’auteur et le contenu du message reçu. Une fois que le client reçoit un message, un nouvel élémentdivest créé avec le nom de l'auteur et le contenu du message ajoutés en tant qu'éléments enfants à l'aide detextContent. Il est ajouté à l’élémentdivprincipal qui affiche les messages.L’envoi d’un message au moyen de la connexion WebSocket nécessite l’appel de la méthode
send. Le premier paramètre de la méthode est le nom du message. Les données du message se trouvent dans les autres paramètres. Dans cet exemple, un message identifié commenewMessageest envoyé au serveur. Le message se compose du nom d’utilisateur et de l’entrée de l’utilisateur dans une zone de texte. Si l’envoi réussit, la valeur de la zone de texte est effacée.-
Exécutez la commande suivante à la racine du projet :
npm i @microsoft/signalr @types/nodeLa commande précédente active :
- Le SignalRclient TypeScript, ce qui permet au client d’envoyer des messages au serveur.
- Les définitions de types TypeScript pour Node.js, qui permettent la vérification au moment de la compilation des types Node.js.
Tester l'application
Vérifiez que l’application fonctionne avec les étapes suivantes :
Exécutez Webpack en mode
release. Dans la fenêtre Console du Gestionnaire de package, exécutez la commande suivante à la racine du projet.npm run releaseCette commande génère les ressources côté client à délivrer pendant l’exécution de l’application. Les ressources sont placées dans le dossier
wwwroot.Webpack a effectué les tâches suivantes :
- Vide le contenu du répertoire
wwwroot. - Converti le TypeScript en JavaScript dans un processus appelé transpilation.
- Modifié le code JavaScript généré pour réduire la taille du fichier dans un processus appelé minification.
- Copie des fichiers JavaScript, CSS et HTML traités à partir de
srcdans le répertoirewwwroot. - Injection des éléments suivants dans le fichier
wwwroot/index.html:- Balise
<link>, référençant le fichierwwwroot/main.<hash>.css. Cette balise est placée immédiatement avant la balise</head>de fermeture. - Balise
<script>, référençant le fichierwwwroot/main.<hash>.jsminifié. Cette balise est placée immédiatement après la balise de fermeture</title>.
- Balise
- Vide le contenu du répertoire
Sélectionnez Déboguer>Démarrer sans débogage pour lancer l’application dans un navigateur sans attacher le débogueur. Le fichier
wwwroot/index.htmlest disponible àhttps://localhost:<port>.En cas d’erreurs de compilation, essayez de fermer et de rouvrir la solution.
Ouvrez une autre instance du navigateur (n’importe quel navigateur) et collez l’URL dans la barre d’adresse.
Choisissez un navigateur, tapez quelque chose dans la zone de texte Message, puis cliquez sur le bouton Envoyer. Le nom unique de l’utilisateur et le message sont affichés instantanément dans les deux pages.
Étapes suivantes
- Hubs fortement typés
- Authentification et autorisation dans ASP.NET Core SignalR
- Protocole Hub MessagePack dans SignalR pour ASP.NET Core
Ressources supplémentaires
Ce tutoriel montre comment utiliser Webpack dans une application web ASP.NET Core SignalR pour regrouper et générer un client écrit en TypeScript. Webpack permet aux développeurs de regrouper et générer les ressources côté client d’une application web.
Dans ce tutoriel, vous allez apprendre à :
- Créer une application ASP.NET Core SignalR
- Configurer le serveur SignalR
- Configurer un pipeline de build à l’aide de Webpack
- Configurer le client TypeScript SignalR
- Activer la communication entre le client et le serveur
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Prerequisites
Visual Studio 2022 avec la charge de travail Développement web et ASP.NET.
Créer l’application web ASP.NET Core
Par défaut, Visual Studio utilise la version de npm qu’il trouve dans son répertoire d’installation. Pour configurer Visual Studio pour rechercher npm dans la variable d’environnement PATH :
Lancez Visual Studio. Dans la fenêtre de démarrage, sélectionnez Continuer sans code.
Accédez à Outils>Options>Projets et solutions>Gestion des packages web>Outils web externes.
Sélectionnez l’entrée
$(PATH)dans la liste. Sélectionnez la flèche vers le haut pour déplacer l’entrée à la deuxième position de la liste, puis sélectionnez OK :
.
Pour créer une application web ASP.NET Core :
- Utilisez l’option de menu Fichier>Nouveau>Projet et choisissez le modèle ASP.NET Core Vide. Cliquez sur Suivant.
- Nommez le projet
SignalRWebpack, puis sélectionnez Créer. - Sélectionnez .NET 8.0 (prise en charge à long terme) dans la liste déroulante Framework. Cliquez sur Créer.
Ajoutez le package NuGet Microsoft.TypeScript.MSBuild au projet :
- Dans Explorateur de solutions, cliquez avec le bouton droit sur le nœud du projet, puis sélectionnez Gérer les packages NuGet. Sous l’onglet Parcourir, recherchez
Microsoft.TypeScript.MSBuild, puis cliquez sur Installer à droite pour installer le package.
Visual Studio ajoute le package NuGet sous le nœud Dépendances dans Explorateur de solutions, ce qui permet la compilation TypeScript dans le projet.
Configurer le serveur
Dans cette section, vous allez configurer l’application web ASP.NET Core pour envoyer et recevoir des messages SignalR.
Dans
Program.cs, appelez AddSignalR :var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Là encore, dans
Program.cs, appelez UseDefaultFiles et UseStaticFiles :var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Le code précédent permet au serveur de localiser et de servir le fichier
index.html. Le fichier est servi si l’utilisateur entre son URL complète ou l’URL racine de l’application web.Créez un répertoire nommé
Hubsdans la racine du projet,SignalRWebpack/, pour la classe hub SignalR.Créez un fichier,
Hubs/ChatHub.cs, avec le code suivant :using Microsoft.AspNetCore.SignalR; namespace SignalRWebpack.Hubs; public class ChatHub : Hub { public async Task NewMessage(long username, string message) => await Clients.All.SendAsync("messageReceived", username, message); }Le code précédent diffuse les messages reçus à tous les utilisateurs connectés, une fois que le serveur les reçoit. Vous n’avez pas besoin d’avoir recours à une méthode générique
onpour recevoir tous les messages. Une méthode nommée après le nom du message est suffisante.Dans cet exemple :
- Le client TypeScript envoie un message identifié comme
newMessage. - La méthode C#
NewMessageattend les données envoyées par le client. - Un appel est effectué pour SendAsync sur Clients.All.
- Les messages reçus sont envoyés à tous les clients connectés au hub.
- Le client TypeScript envoie un message identifié comme
Ajoutez l’instruction
usingsuivante en haut deProgram.cspour résoudre la référenceChatHub:using SignalRWebpack.Hubs;Dans
Program.cs, mappez l’itinéraire/hubau hubChatHub. Remplacez le code qui afficheHello World!par le code suivant :app.MapHub<ChatHub>("/hub");
Configurer le client
Dans cette section, vous allez créer un projet Node.js pour convertir TypeScript en ressources JavaScript et regrouper des ressources côté client, notamment HTML et CSS, à l’aide de Webpack.
Exécutez la commande suivante dans la racine du projet pour créer un fichier
package.json:npm init -yAjoutez la propriété mise en surbrillance au fichier
package.jsonet enregistrez les modifications apportées au fichier :{ "name": "SignalRWebpack", "version": "1.0.0", "private": true, "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }La définition de la propriété
privatesurtrueempêche les avertissements d’installation de package à l’étape suivante.Installez les packages npm nécessaires. À partir de la racine du projet, exécutez la commande suivante :
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliL’option
-Edésactive le comportement par défaut de npm qui consiste à écrire des opérateurs de plage de versionnage sémantique danspackage.json. Par exemple,"webpack": "5.76.1"peut être utilisé à la place de"webpack": "^5.76.1". Cette option empêche les mises à niveau involontaires vers des versions de package plus récentes.Pour plus d’informations, consultez la documentation npm-install.
Remplacez la propriété
scriptsdu fichierpackage.jsonpar le code suivant :"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Les scripts suivants sont définis :
-
build: Regroupe les ressources côté client en mode de développement et surveille les changements de fichier. L’observateur de fichiers entraîne la régénération du paquet chaque fois qu’un fichier de projet change. L'optionmodedésactive les optimisations de production, telles que le tree shaking et la minification. utilisezbuilduniquement dans le développement. -
release: Regroupe les ressources côté client en mode de production. -
publish: Exécute le scriptreleasepour regrouper les ressources côté client en mode de production. La commande appelle la commande publish de CLI .NET pour publier l’application.
-
Créez un fichier nommé
webpack.config.jsà la racine du projet avec le code suivant :const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "wwwroot"), filename: "[name].[chunkhash].js", publicPath: "/", }, resolve: { extensions: [".js", ".ts"], }, module: { rules: [ { test: /\.ts$/, use: "ts-loader", }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"], }, ], }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", }), new MiniCssExtractPlugin({ filename: "css/[name].[chunkhash].css", }), ], };Le fichier précédent configure le processus de compilation Webpack :
- La propriété
outputremplace la valeur par défaut dedist. Le paquet est plutôt émis dans le répertoirewwwroot. - Le tableau
resolve.extensionsinclut.jspour importer le code JavaScript du client SignalR.
- La propriété
Créez un nouveau répertoire nommé
srcà la racine du projet,SignalRWebpack/, pour le code client.Copiez le répertoire
srcet son contenu de l'exemple de projet vers la racine du projet. Le répertoiresrccontient les fichiers suivants :index.html, qui définit le balisage réutilisable de la page d’accueil :<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>ASP.NET Core SignalR with TypeScript and Webpack</title> </head> <body> <div id="divMessages" class="messages"></div> <div class="input-zone"> <label id="lblMessage" for="tbMessage">Message:</label> <input id="tbMessage" class="input-zone-input" type="text" /> <button id="btnSend">Send</button> </div> </body> </html>css/main.css, qui fournit des styles CSS pour la page d’accueil :*, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; } .input-zone { align-items: center; display: flex; flex-direction: row; margin: 10px; } .input-zone-input { flex: 1; margin-right: 10px; } .message-author { font-weight: bold; } .messages { border: 1px solid #000; margin: 10px; max-height: 300px; min-height: 300px; overflow-y: auto; padding: 5px; }tsconfig.json, qui configure le compilateur TypeScript pour produire du JavaScript compatible ECMAScript 5 :{ "compilerOptions": { "target": "es5" } }index.ts:import * as signalR from "@microsoft/signalr"; import "./css/main.css"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { const m = document.createElement("div"); m.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`; divMessages.appendChild(m); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch((err) => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.key === "Enter") { send(); } }); btnSend.addEventListener("click", send); function send() { connection.send("newMessage", username, tbMessage.value) .then(() => (tbMessage.value = "")); }Le code précédent récupère les références aux éléments DOM et attache deux gestionnaires d’événements :
-
keyup: se déclenche lorsque l’utilisateur tape dans la zone de textetbMessageet appelle la fonctionsendlorsque l’utilisateur appuie sur la touche Entrée. -
click: se déclenche lorsque l’utilisateur sélectionne le bouton Envoyer et la fonctionsendest appelée.
La classe
HubConnectionBuildercrée un générateur pour configurer la connexion de serveur. La fonctionwithUrlconfigure l’URL du hub.SignalR permet l’échange de messages entre un client et un serveur. Chaque message a un nom spécifique. Par exemple, les messages portant le nom
messageReceivedpeuvent exécuter la logique responsable de l’affichage du nouveau message dans la zone de messages. L’écoute d’un message spécifique peut être effectuée au moyen de la fonctionon. N’importe quel nombre de noms de messages peuvent être écoutés. Vous pouvez aussi passer des paramètres au message, comme le nom de l’auteur et le contenu du message reçu. Une fois que le client reçoit un message, un nouvel élémentdivest créé avec le nom de l'auteur et le contenu du message ajoutés en tant qu'éléments enfants à l'aide detextContent. Il est ajouté à l’élémentdivprincipal qui affiche les messages.L’envoi d’un message au moyen de la connexion WebSocket nécessite l’appel de la méthode
send. Le premier paramètre de la méthode est le nom du message. Les données du message se trouvent dans les autres paramètres. Dans cet exemple, un message identifié commenewMessageest envoyé au serveur. Le message se compose du nom d’utilisateur et de l’entrée de l’utilisateur dans une zone de texte. Si l’envoi réussit, la valeur de la zone de texte est effacée.-
Exécutez la commande suivante à la racine du projet :
npm i @microsoft/signalr @types/nodeLa commande précédente active :
- Le SignalRclient TypeScript, ce qui permet au client d’envoyer des messages au serveur.
- Les définitions de types TypeScript pour Node.js, qui permettent la vérification au moment de la compilation des types Node.js.
Tester l'application
Vérifiez que l’application fonctionne avec les étapes suivantes :
Exécutez Webpack en mode
release. Dans la fenêtre Console du Gestionnaire de package, exécutez la commande suivante à la racine du projet.npm run releaseCette commande génère les ressources côté client à délivrer pendant l’exécution de l’application. Les ressources sont placées dans le dossier
wwwroot.Webpack a effectué les tâches suivantes :
- Vide le contenu du répertoire
wwwroot. - Converti le TypeScript en JavaScript dans un processus appelé transpilation.
- Modifié le code JavaScript généré pour réduire la taille du fichier dans un processus appelé minification.
- Copie des fichiers JavaScript, CSS et HTML traités à partir de
srcdans le répertoirewwwroot. - Injection des éléments suivants dans le fichier
wwwroot/index.html:- Balise
<link>, référençant le fichierwwwroot/main.<hash>.css. Cette balise est placée immédiatement avant la balise</head>de fermeture. - Balise
<script>, référençant le fichierwwwroot/main.<hash>.jsminifié. Cette balise est placée immédiatement après la balise de fermeture</title>.
- Balise
- Vide le contenu du répertoire
Sélectionnez Déboguer>Démarrer sans débogage pour lancer l’application dans un navigateur sans attacher le débogueur. Le fichier
wwwroot/index.htmlest disponible àhttps://localhost:<port>.En cas d’erreurs de compilation, essayez de fermer et de rouvrir la solution.
Ouvrez une autre instance du navigateur (n’importe quel navigateur) et collez l’URL dans la barre d’adresse.
Choisissez un navigateur, tapez quelque chose dans la zone de texte Message, puis cliquez sur le bouton Envoyer. Le nom unique de l’utilisateur et le message sont affichés instantanément dans les deux pages.
Étapes suivantes
- Hubs fortement typés
- Authentification et autorisation dans ASP.NET Core SignalR
- Protocole Hub MessagePack dans SignalR pour ASP.NET Core
Ressources supplémentaires
Ce tutoriel montre comment utiliser Webpack dans une application web ASP.NET Core SignalR pour regrouper et générer un client écrit en TypeScript. Webpack permet aux développeurs de regrouper et générer les ressources côté client d’une application web.
Dans ce tutoriel, vous allez apprendre à :
- Créer une application ASP.NET Core SignalR
- Configurer le serveur SignalR
- Configurer un pipeline de build à l’aide de Webpack
- Configurer le client TypeScript SignalR
- Activer la communication entre le client et le serveur
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Prerequisites
Visual Studio 2022 avec la charge de travail Développement web et ASP.NET.
Créer l’application web ASP.NET Core
Par défaut, Visual Studio utilise la version de npm qu’il trouve dans son répertoire d’installation. Pour configurer Visual Studio pour rechercher npm dans la variable d’environnement PATH :
Lancez Visual Studio. Dans la fenêtre de démarrage, sélectionnez Continuer sans code.
Accédez à Outils>Options>Projets et solutions>Gestion des packages web>Outils web externes.
Sélectionnez l’entrée
$(PATH)dans la liste. Sélectionnez la flèche vers le haut pour déplacer l’entrée à la deuxième position de la liste, puis sélectionnez OK :
.
Pour créer une application web ASP.NET Core :
- Utilisez l’option de menu Fichier>Nouveau>Projet et choisissez le modèle ASP.NET Core Vide. Cliquez sur Suivant.
- Nommez le projet
SignalRWebpack, puis sélectionnez Créer. - Sélectionnez .NET 7.0 (Support standard) dans la liste déroulante Framework. Cliquez sur Créer.
Ajoutez le package NuGet Microsoft.TypeScript.MSBuild au projet :
- Dans Explorateur de solutions, cliquez avec le bouton droit sur le nœud du projet, puis sélectionnez Gérer les packages NuGet. Sous l’onglet Parcourir, recherchez
Microsoft.TypeScript.MSBuild, puis cliquez sur Installer à droite pour installer le package.
Visual Studio ajoute le package NuGet sous le nœud Dépendances dans Explorateur de solutions, ce qui permet la compilation TypeScript dans le projet.
Configurer le serveur
Dans cette section, vous allez configurer l’application web ASP.NET Core pour envoyer et recevoir des messages SignalR.
Dans
Program.cs, appelez AddSignalR :var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Là encore, dans
Program.cs, appelez UseDefaultFiles et UseStaticFiles :var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Le code précédent permet au serveur de localiser et de servir le fichier
index.html. Le fichier est servi si l’utilisateur entre son URL complète ou l’URL racine de l’application web.Créez un répertoire nommé
Hubsdans la racine du projet,SignalRWebpack/, pour la classe hub SignalR.Créez un fichier,
Hubs/ChatHub.cs, avec le code suivant :using Microsoft.AspNetCore.SignalR; namespace SignalRWebpack.Hubs; public class ChatHub : Hub { public async Task NewMessage(long username, string message) => await Clients.All.SendAsync("messageReceived", username, message); }Le code précédent diffuse les messages reçus à tous les utilisateurs connectés, une fois que le serveur les reçoit. Vous n’avez pas besoin d’avoir recours à une méthode générique
onpour recevoir tous les messages. Une méthode nommée après le nom du message est suffisante.Dans cet exemple :
- Le client TypeScript envoie un message identifié comme
newMessage. - La méthode C#
NewMessageattend les données envoyées par le client. - Un appel est effectué pour SendAsync sur Clients.All.
- Les messages reçus sont envoyés à tous les clients connectés au hub.
- Le client TypeScript envoie un message identifié comme
Ajoutez l’instruction
usingsuivante en haut deProgram.cspour résoudre la référenceChatHub:using SignalRWebpack.Hubs;Dans
Program.cs, mappez l’itinéraire/hubau hubChatHub. Remplacez le code qui afficheHello World!par le code suivant :app.MapHub<ChatHub>("/hub");
Configurer le client
Dans cette section, vous allez créer un projet Node.js pour convertir TypeScript en ressources JavaScript et regrouper des ressources côté client, notamment HTML et CSS, à l’aide de Webpack.
Exécutez la commande suivante dans la racine du projet pour créer un fichier
package.json:npm init -yAjoutez la propriété mise en surbrillance au fichier
package.jsonet enregistrez les modifications apportées au fichier :{ "name": "SignalRWebpack", "version": "1.0.0", "private": true, "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }La définition de la propriété
privatesurtrueempêche les avertissements d’installation de package à l’étape suivante.Installez les packages npm nécessaires. À partir de la racine du projet, exécutez la commande suivante :
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliL’option
-Edésactive le comportement par défaut de npm qui consiste à écrire des opérateurs de plage de versionnage sémantique danspackage.json. Par exemple,"webpack": "5.76.1"peut être utilisé à la place de"webpack": "^5.76.1". Cette option empêche les mises à niveau involontaires vers des versions de package plus récentes.Pour plus d’informations, consultez la documentation npm-install.
Remplacez la propriété
scriptsdu fichierpackage.jsonpar le code suivant :"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Les scripts suivants sont définis :
-
build: Regroupe les ressources côté client en mode de développement et surveille les changements de fichier. L’observateur de fichiers entraîne la régénération du paquet chaque fois qu’un fichier de projet change. L'optionmodedésactive les optimisations de production, telles que le tree shaking et la minification. utilisezbuilduniquement dans le développement. -
release: Regroupe les ressources côté client en mode de production. -
publish: Exécute le scriptreleasepour regrouper les ressources côté client en mode de production. La commande appelle la commande publish de CLI .NET pour publier l’application.
-
Créez un fichier nommé
webpack.config.jsà la racine du projet avec le code suivant :const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "wwwroot"), filename: "[name].[chunkhash].js", publicPath: "/", }, resolve: { extensions: [".js", ".ts"], }, module: { rules: [ { test: /\.ts$/, use: "ts-loader", }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"], }, ], }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", }), new MiniCssExtractPlugin({ filename: "css/[name].[chunkhash].css", }), ], };Le fichier précédent configure le processus de compilation Webpack :
- La propriété
outputremplace la valeur par défaut dedist. Le paquet est plutôt émis dans le répertoirewwwroot. - Le tableau
resolve.extensionsinclut.jspour importer le code JavaScript du client SignalR.
- La propriété
Copiez le répertoire
srcet son contenu de l'exemple de projet vers la racine du projet. Le répertoiresrccontient les fichiers suivants :index.html, qui définit le balisage réutilisable de la page d’accueil :<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>ASP.NET Core SignalR with TypeScript and Webpack</title> </head> <body> <div id="divMessages" class="messages"></div> <div class="input-zone"> <label id="lblMessage" for="tbMessage">Message:</label> <input id="tbMessage" class="input-zone-input" type="text" /> <button id="btnSend">Send</button> </div> </body> </html>css/main.css, qui fournit des styles CSS pour la page d’accueil :*, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; } .input-zone { align-items: center; display: flex; flex-direction: row; margin: 10px; } .input-zone-input { flex: 1; margin-right: 10px; } .message-author { font-weight: bold; } .messages { border: 1px solid #000; margin: 10px; max-height: 300px; min-height: 300px; overflow-y: auto; padding: 5px; }tsconfig.json, qui configure le compilateur TypeScript pour produire du JavaScript compatible ECMAScript 5 :{ "compilerOptions": { "target": "es5" } }index.ts:import * as signalR from "@microsoft/signalr"; import "./css/main.css"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { const m = document.createElement("div"); m.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`; divMessages.appendChild(m); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch((err) => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.key === "Enter") { send(); } }); btnSend.addEventListener("click", send); function send() { connection.send("newMessage", username, tbMessage.value) .then(() => (tbMessage.value = "")); }Le code précédent récupère les références aux éléments DOM et attache deux gestionnaires d’événements :
-
keyup: se déclenche lorsque l’utilisateur tape dans la zone de textetbMessageet appelle la fonctionsendlorsque l’utilisateur appuie sur la touche Entrée. -
click: se déclenche lorsque l’utilisateur sélectionne le bouton Envoyer et la fonctionsendest appelée.
La classe
HubConnectionBuildercrée un générateur pour configurer la connexion de serveur. La fonctionwithUrlconfigure l’URL du hub.SignalR permet l’échange de messages entre un client et un serveur. Chaque message a un nom spécifique. Par exemple, les messages portant le nom
messageReceivedpeuvent exécuter la logique responsable de l’affichage du nouveau message dans la zone de messages. L’écoute d’un message spécifique peut être effectuée au moyen de la fonctionon. N’importe quel nombre de noms de messages peuvent être écoutés. Vous pouvez aussi passer des paramètres au message, comme le nom de l’auteur et le contenu du message reçu. Une fois que le client reçoit un message, un nouvel élémentdivest créé avec le nom de l'auteur et le contenu du message ajoutés en tant qu'éléments enfants à l'aide detextContent. Il est ajouté à l’élémentdivprincipal qui affiche les messages.L’envoi d’un message au moyen de la connexion WebSocket nécessite l’appel de la méthode
send. Le premier paramètre de la méthode est le nom du message. Les données du message se trouvent dans les autres paramètres. Dans cet exemple, un message identifié commenewMessageest envoyé au serveur. Le message se compose du nom d’utilisateur et de l’entrée de l’utilisateur dans une zone de texte. Si l’envoi réussit, la valeur de la zone de texte est effacée.-
Exécutez la commande suivante à la racine du projet :
npm i @microsoft/signalr @types/nodeLa commande précédente active :
- Le SignalRclient TypeScript, ce qui permet au client d’envoyer des messages au serveur.
- Les définitions de types TypeScript pour Node.js, qui permettent la vérification au moment de la compilation des types Node.js.
Tester l'application
Vérifiez que l’application fonctionne avec les étapes suivantes :
Exécutez Webpack en mode
release. Dans la fenêtre Console du Gestionnaire de package, exécutez la commande suivante à la racine du projet.npm run releaseCette commande génère les ressources côté client à délivrer pendant l’exécution de l’application. Les ressources sont placées dans le dossier
wwwroot.Webpack a effectué les tâches suivantes :
- Vide le contenu du répertoire
wwwroot. - Converti le TypeScript en JavaScript dans un processus appelé transpilation.
- Modifié le code JavaScript généré pour réduire la taille du fichier dans un processus appelé minification.
- Copie des fichiers JavaScript, CSS et HTML traités à partir de
srcdans le répertoirewwwroot. - Injection des éléments suivants dans le fichier
wwwroot/index.html:- Balise
<link>, référençant le fichierwwwroot/main.<hash>.css. Cette balise est placée immédiatement avant la balise</head>de fermeture. - Balise
<script>, référençant le fichierwwwroot/main.<hash>.jsminifié. Cette balise est placée immédiatement après la balise de fermeture</title>.
- Balise
- Vide le contenu du répertoire
Sélectionnez Déboguer>Démarrer sans débogage pour lancer l’application dans un navigateur sans attacher le débogueur. Le fichier
wwwroot/index.htmlest disponible àhttps://localhost:<port>.En cas d’erreurs de compilation, essayez de fermer et de rouvrir la solution.
Ouvrez une autre instance du navigateur (n’importe quel navigateur) et collez l’URL dans la barre d’adresse.
Choisissez un navigateur, tapez quelque chose dans la zone de texte Message, puis cliquez sur le bouton Envoyer. Le nom unique de l’utilisateur et le message sont affichés instantanément dans les deux pages.
Étapes suivantes
- Hubs fortement typés
- Authentification et autorisation dans ASP.NET Core SignalR
- Protocole Hub MessagePack dans SignalR pour ASP.NET Core
Ressources supplémentaires
Ce tutoriel montre comment utiliser Webpack dans une application web ASP.NET Core SignalR pour regrouper et générer un client écrit en TypeScript. Webpack permet aux développeurs de regrouper et générer les ressources côté client d’une application web.
Dans ce tutoriel, vous allez apprendre à :
- Créer une application ASP.NET Core SignalR
- Configurer le serveur SignalR
- Configurer un pipeline de build à l’aide de Webpack
- Configurer le client TypeScript SignalR
- Activer la communication entre le client et le serveur
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Prerequisites
- Visual Studio 2022 avec la charge de travail Développement web et ASP.NET.
- Kit de développement .NET 6
Créer l’application web ASP.NET Core
Par défaut, Visual Studio utilise la version de npm qu’il trouve dans son répertoire d’installation. Pour configurer Visual Studio pour rechercher npm dans la variable d’environnement PATH :
Lancez Visual Studio. Dans la fenêtre de démarrage, sélectionnez Continuer sans code.
Accédez à Outils>Options>Projets et solutions>Gestion des packages web>Outils web externes.
Sélectionnez l’entrée
$(PATH)dans la liste. Sélectionnez la flèche vers le haut pour déplacer l’entrée à la deuxième position de la liste, puis sélectionnez OK :
.
Pour créer une application web ASP.NET Core :
- Utilisez l’option de menu Fichier>Nouveau>Projet et choisissez le modèle ASP.NET Core Vide. Cliquez sur Suivant.
- Nommez le projet
SignalRWebpack, puis sélectionnez Créer. - Sélectionnez .NET 6.0 (support à long terme) dans la liste déroulante Framework . Cliquez sur Créer.
Ajoutez le package NuGet Microsoft.TypeScript.MSBuild au projet :
- Dans Explorateur de solutions, cliquez avec le bouton droit sur le nœud du projet, puis sélectionnez Gérer les packages NuGet. Sous l’onglet Parcourir, recherchez
Microsoft.TypeScript.MSBuild, puis cliquez sur Installer à droite pour installer le package.
Visual Studio ajoute le package NuGet sous le nœud Dépendances dans Explorateur de solutions, ce qui permet la compilation TypeScript dans le projet.
Configurer le serveur
Dans cette section, vous allez configurer l’application web ASP.NET Core pour envoyer et recevoir des messages SignalR.
Dans
Program.cs, appelez AddSignalR :var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Là encore, dans
Program.cs, appelez UseDefaultFiles et UseStaticFiles :var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Le code précédent permet au serveur de localiser et de servir le fichier
index.html. Le fichier est servi si l’utilisateur entre son URL complète ou l’URL racine de l’application web.Créez un répertoire nommé
Hubsdans la racine du projet,SignalRWebpack/, pour la classe hub SignalR.Créez un fichier,
Hubs/ChatHub.cs, avec le code suivant :using Microsoft.AspNetCore.SignalR; namespace SignalRWebpack.Hubs; public class ChatHub : Hub { public async Task NewMessage(long username, string message) => await Clients.All.SendAsync("messageReceived", username, message); }Le code précédent diffuse les messages reçus à tous les utilisateurs connectés, une fois que le serveur les reçoit. Vous n’avez pas besoin d’avoir recours à une méthode générique
onpour recevoir tous les messages. Une méthode nommée après le nom du message est suffisante.Dans cet exemple, le client TypeScript envoie un message identifié comme
newMessage. La méthode C#NewMessageattend les données envoyées par le client. Un appel est effectué pour SendAsync sur Clients.All. Les messages reçus sont envoyés à tous les clients connectés au hub.Ajoutez l’instruction
usingsuivante en haut deProgram.cspour résoudre la référenceChatHub:using SignalRWebpack.Hubs;Dans
Program.cs, mappez l’itinéraire/hubau hubChatHub. Remplacez le code qui afficheHello World!par le code suivant :app.MapHub<ChatHub>("/hub");
Configurer le client
Dans cette section, vous allez créer un projet Node.js pour convertir TypeScript en ressources JavaScript et regrouper des ressources côté client, notamment HTML et CSS, à l’aide de Webpack.
Exécutez la commande suivante dans la racine du projet pour créer un fichier
package.json:npm init -yAjoutez la propriété mise en surbrillance au fichier
package.jsonet enregistrez les modifications apportées au fichier :{ "name": "SignalRWebpack", "version": "1.0.0", "private": true, "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }La définition de la propriété
privatesurtrueempêche les avertissements d’installation de package à l’étape suivante.Installez les packages npm nécessaires. À partir de la racine du projet, exécutez la commande suivante :
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliL’option
-Edésactive le comportement par défaut de npm qui consiste à écrire des opérateurs de plage de versionnage sémantique danspackage.json. Par exemple,"webpack": "5.70.0"peut être utilisé à la place de"webpack": "^5.70.0". Cette option empêche les mises à niveau involontaires vers des versions de package plus récentes.Pour plus d’informations, consultez la documentation npm-install.
Remplacez la propriété
scriptsdu fichierpackage.jsonpar le code suivant :"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Les scripts suivants sont définis :
-
build: Regroupe les ressources côté client en mode de développement et surveille les changements de fichier. L’observateur de fichiers entraîne la régénération du paquet chaque fois qu’un fichier de projet change. L'optionmodedésactive les optimisations de production, telles que le tree shaking et la minification. utilisezbuilduniquement dans le développement. -
release: Regroupe les ressources côté client en mode de production. -
publish: Exécute le scriptreleasepour regrouper les ressources côté client en mode de production. La commande appelle la commande publish de CLI .NET pour publier l’application.
-
Créez un fichier nommé
webpack.config.jsà la racine du projet avec le code suivant :const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "wwwroot"), filename: "[name].[chunkhash].js", publicPath: "/", }, resolve: { extensions: [".js", ".ts"], }, module: { rules: [ { test: /\.ts$/, use: "ts-loader", }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"], }, ], }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html", }), new MiniCssExtractPlugin({ filename: "css/[name].[chunkhash].css", }), ], };Le fichier précédent configure le processus de compilation Webpack :
- La propriété
outputremplace la valeur par défaut dedist. Le paquet est plutôt émis dans le répertoirewwwroot. - Le tableau
resolve.extensionsinclut.jspour importer le code JavaScript du client SignalR.
- La propriété
Copiez le répertoire
srcet son contenu de l'exemple de projet vers la racine du projet. Le répertoiresrccontient les fichiers suivants :index.html, qui définit le balisage réutilisable de la page d’accueil :<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>ASP.NET Core SignalR with TypeScript and Webpack</title> </head> <body> <div id="divMessages" class="messages"></div> <div class="input-zone"> <label id="lblMessage" for="tbMessage">Message:</label> <input id="tbMessage" class="input-zone-input" type="text" /> <button id="btnSend">Send</button> </div> </body> </html>css/main.css, qui fournit des styles CSS pour la page d’accueil :*, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; } .input-zone { align-items: center; display: flex; flex-direction: row; margin: 10px; } .input-zone-input { flex: 1; margin-right: 10px; } .message-author { font-weight: bold; } .messages { border: 1px solid #000; margin: 10px; max-height: 300px; min-height: 300px; overflow-y: auto; padding: 5px; }tsconfig.json, qui configure le compilateur TypeScript pour produire du JavaScript compatible ECMAScript 5 :{ "compilerOptions": { "target": "es5" } }index.ts:import * as signalR from "@microsoft/signalr"; import "./css/main.css"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { const m = document.createElement("div"); m.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`; divMessages.appendChild(m); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch((err) => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.key === "Enter") { send(); } }); btnSend.addEventListener("click", send); function send() { connection.send("newMessage", username, tbMessage.value) .then(() => (tbMessage.value = "")); }
Le code précédent récupère les références aux éléments DOM et attache deux gestionnaires d’événements :
-
keyup: se déclenche lorsque l’utilisateur tape dans la zone de textetbMessageet appelle la fonctionsendlorsque l’utilisateur appuie sur la touche Entrée. -
click: se déclenche lorsque l’utilisateur sélectionne le bouton Envoyer et la fonctionsendest appelée.
La classe
HubConnectionBuildercrée un générateur pour configurer la connexion de serveur. La fonctionwithUrlconfigure l’URL du hub.SignalR permet l’échange de messages entre un client et un serveur. Chaque message a un nom spécifique. Par exemple, les messages portant le nom
messageReceivedpeuvent exécuter la logique responsable de l’affichage du nouveau message dans la zone de messages. L’écoute d’un message spécifique peut être effectuée au moyen de la fonctionon. N’importe quel nombre de noms de messages peuvent être écoutés. Vous pouvez aussi passer des paramètres au message, comme le nom de l’auteur et le contenu du message reçu. Une fois que le client reçoit un message, un nouvel élémentdivest créé avec le nom de l'auteur et le contenu du message ajoutés en tant qu'éléments enfants à l'aide detextContent. Il est ajouté à l’élémentdivprincipal qui affiche les messages.L’envoi d’un message au moyen de la connexion WebSocket nécessite l’appel de la méthode
send. Le premier paramètre de la méthode est le nom du message. Les données du message se trouvent dans les autres paramètres. Dans cet exemple, un message identifié commenewMessageest envoyé au serveur. Le message se compose du nom d’utilisateur et de l’entrée de l’utilisateur dans une zone de texte. Si l’envoi réussit, la valeur de la zone de texte est effacée.Exécutez la commande suivante à la racine du projet :
npm i @microsoft/signalr @types/nodeLa commande précédente active :
- Le SignalRclient TypeScript, ce qui permet au client d’envoyer des messages au serveur.
- Les définitions de types TypeScript pour Node.js, qui permettent la vérification au moment de la compilation des types Node.js.
Tester l'application
Vérifiez que l’application fonctionne avec les étapes suivantes :
Exécutez Webpack en mode
release. Dans la fenêtre Console du Gestionnaire de package, exécutez la commande suivante à la racine du projet. Si vous ne vous trouvez pas à la racine du projet, tapezcd SignalRWebpackavant d’entrer la commande.npm run releaseCette commande génère les ressources côté client à délivrer pendant l’exécution de l’application. Les ressources sont placées dans le dossier
wwwroot.Webpack a effectué les tâches suivantes :
- Vide le contenu du répertoire
wwwroot. - Converti le TypeScript en JavaScript dans un processus appelé transpilation.
- Modifié le code JavaScript généré pour réduire la taille du fichier dans un processus appelé minification.
- Copie des fichiers JavaScript, CSS et HTML traités à partir de
srcdans le répertoirewwwroot. - Injection des éléments suivants dans le fichier
wwwroot/index.html:- Balise
<link>, référençant le fichierwwwroot/main.<hash>.css. Cette balise est placée immédiatement avant la balise</head>de fermeture. - Balise
<script>, référençant le fichierwwwroot/main.<hash>.jsminifié. Cette balise est placée immédiatement après la balise de fermeture</title>.
- Balise
- Vide le contenu du répertoire
Sélectionnez Déboguer>Démarrer sans débogage pour lancer l’application dans un navigateur sans attacher le débogueur. Le fichier
wwwroot/index.htmlest disponible àhttps://localhost:<port>.Si vous obtenez des erreurs de compilation, essayez de fermer et de rouvrir la solution.
Ouvrez une autre instance du navigateur (n’importe quel navigateur) et collez l’URL dans la barre d’adresse.
Choisissez un navigateur, tapez quelque chose dans la zone de texte Message, puis cliquez sur le bouton Envoyer. Le nom unique de l’utilisateur et le message sont affichés instantanément dans les deux pages.
Étapes suivantes
- Hubs fortement typés
- Authentification et autorisation dans ASP.NET Core SignalR
- Protocole Hub MessagePack dans SignalR pour ASP.NET Core
Ressources supplémentaires
Ce tutoriel montre comment utiliser Webpack dans une application web ASP.NET Core SignalR pour regrouper et générer un client écrit en TypeScript. Webpack permet aux développeurs de regrouper et générer les ressources côté client d’une application web.
Dans ce tutoriel, vous allez apprendre à :
- Structurer une application de démarrage ASP.NET Core SignalR
- Configurer le client TypeScript SignalR
- Configurer un pipeline de build à l’aide de Webpack
- Configurer le serveur SignalR
- Activer la communication entre le client et le serveur
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Prerequisites
- Visual Studio 2019 avec la charge de travail ASP.NET et développement web
- SDK .NET Core 3.0 ou ultérieur
- Node.js avec npm
Créer l’application web ASP.NET Core
Configurez Visual Studio pour rechercher npm dans la variable d'environnement PATH. Par défaut, Visual Studio utilise la version de npm qu’il trouve dans son répertoire d’installation. Suivez ces instructions dans Visual Studio :
Lancez Visual Studio. Dans la fenêtre de démarrage, sélectionnez Continuer sans code.
Accédez à Outils>Options>Projets et solutions>Gestion des packages web>Outils web externes.
Sélectionnez l’entrée $(PATH) dans la liste. Sélectionnez la flèche vers le haut pour déplacer l’entrée à la deuxième position de la liste, puis sélectionnez OK.
.
La configuration de Visual Studio est terminée.
- Utilisez l’option de menu Fichier>Nouveau>Projet et choisissez le modèle Application web ASP.NET Core. Cliquez sur Suivant.
- Nommez le projet *SignalRWebPac``, puis sélectionnez Créer.
- Sélectionnez .NET Core dans la liste déroulante du framework cible, puis ASP.NET Core 3.1 dans la liste déroulante du sélecteur de framework. Sélectionnez le modèle Vide, puis sélectionnez Créer.
Ajoutez le package Microsoft.TypeScript.MSBuild au projet :
- Dans Explorateur de solutions (panneau droit), cliquez avec le bouton droit sur le nœud du projet, puis sélectionnez Gérer les packages NuGet. Dans l'onglet Parcourir, recherchez
Microsoft.TypeScript.MSBuild, puis cliquez sur Installer à droite pour installer le package.
Visual Studio ajoute le package NuGet sous le nœud Dépendances dans Explorateur de solutions, ce qui permet la compilation TypeScript dans le projet.
Configurer Webpack et TypeScript
Les étapes suivantes configurent la conversion de TypeScript en JavaScript et le regroupement des ressources côté client.
Exécutez la commande suivante dans la racine du projet pour créer un fichier
package.json:npm init -yAjoutez la propriété mise en surbrillance au fichier
package.jsonet enregistrez les modifications apportées au fichier :{ "name": "SignalRWebPack", "version": "1.0.0", "private": true, "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }La définition de la propriété
privatesurtrueempêche les avertissements d’installation de package à l’étape suivante.Installez les packages npm nécessaires. À partir de la racine du projet, exécutez la commande suivante :
npm i -D -E clean-webpack-plugin@3.0.0 css-loader@3.4.2 html-webpack-plugin@3.2.0 mini-css-extract-plugin@0.9.0 ts-loader@6.2.1 typescript@3.7.5 webpack@4.41.5 webpack-cli@3.3.10Détails de commande à prendre en compte :
- Un numéro de version suit le signe
@pour chaque nom de package. npm installe ces versions de package spécifiques. - L’option
-Edésactive le comportement par défaut de npm consistant à écrire des opérateurs de plage de gestion sémantique des versions dans packagejson. Par exemple,"webpack": "4.41.5"peut être utilisé à la place de"webpack": "^4.41.5". Cette option empêche les mises à niveau involontaires vers des versions de package plus récentes.
Consultez la documentation npm-install pour plus de détails.
- Un numéro de version suit le signe
Remplacez la propriété
scriptsdu fichierpackage.jsonpar le code suivant :"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Explication des scripts :
-
build: Regroupe les ressources côté client en mode de développement et surveille les changements de fichier. L’observateur de fichiers entraîne la régénération du paquet chaque fois qu’un fichier de projet change. L'optionmodedésactive les optimisations de production, telles que le tree shaking et la minification. Utilisez uniquementbuilddans le développement. -
release: Regroupe les ressources côté client en mode de production. -
publish: Exécute le scriptreleasepour regrouper les ressources côté client en mode de production. La commande appelle la commande publish de CLI .NET pour publier l’application.
-
Créez un fichier nommé
webpack.config.jsà la racine du projet avec le code suivant :const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "wwwroot"), filename: "[name].[chunkhash].js", publicPath: "/" }, resolve: { extensions: [".js", ".ts"] }, module: { rules: [ { test: /\.ts$/, use: "ts-loader" }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"] } ] }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: "./src/index.html" }), new MiniCssExtractPlugin({ filename: "css/[name].[chunkhash].css" }) ] };Le fichier précédent configure la compilation Webpack. Détails de configuration à prendre en compte :
- La propriété
outputremplace la valeur par défaut dedist. Le paquet est plutôt émis dans le répertoirewwwroot. - Le tableau
resolve.extensionsinclut.jspour importer le code JavaScript du client SignalR.
- La propriété
Créez un répertoire src à la racine du projet pour stocker les ressources côté client du projet.
Créez
src/index.htmlavec le balisage suivant.<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>ASP.NET Core SignalR</title> </head> <body> <div id="divMessages" class="messages"> </div> <div class="input-zone"> <label id="lblMessage" for="tbMessage">Message:</label> <input id="tbMessage" class="input-zone-input" type="text" /> <button id="btnSend">Send</button> </div> </body> </html>Le code HTML précédent définit le balisage réutilisable de la page d’accueil.
Créez un répertoire src/css. Son objectif est de stocker les fichiers
.cssdu projet.Créez
src/css/main.cssavec le CSS suivant :*, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; } .input-zone { align-items: center; display: flex; flex-direction: row; margin: 10px; } .input-zone-input { flex: 1; margin-right: 10px; } .message-author { font-weight: bold; } .messages { border: 1px solid #000; margin: 10px; max-height: 300px; min-height: 300px; overflow-y: auto; padding: 5px; }Le fichier
main.cssprécédent définit le style de l’application.Créez
src/tsconfig.jsonavec le JSON suivant :{ "compilerOptions": { "target": "es5" } }Le code précédent configure le compilateur TypeScript pour produire du code JavaScript compatible ECMAScript 5.
Créez
src/index.tsavec le code suivant :import "./css/main.css"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.key === "Enter") { send(); } }); btnSend.addEventListener("click", send); function send() { }Le code TypeScript précédent récupère les références aux éléments DOM et joint deux gestionnaires d’événements :
-
keyup: Cet événement se déclenche quand l’utilisateur tape des données dans la zone de textetbMessage. La fonctionsendest appelée quand l’utilisateur appuie sur la touche Entrée. -
click: Cet événement se déclenche quand l’utilisateur clique sur le bouton Envoyer. La fonctionsendest appelée.
-
Configurer l’application
Dans
Startup.Configure, ajoutez des appels à UseDefaultFiles(IApplicationBuilder) et UseStaticFiles(IApplicationBuilder).public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseDefaultFiles(); app.UseStaticFiles(); app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/hub"); }); }Le code précédent permet au serveur de localiser et de servir le fichier
index.html. Le fichier est servi si l’utilisateur entre son URL complète ou l’URL racine de l’application web.À la fin de
Startup.Configure, assignez une route /hub au hubChatHub. Remplacez le code qui affiche Hello World! par la ligne suivante :app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/hub"); });Dans
Startup.ConfigureServices, appelez AddSignalR.services.AddSignalR();Créez un répertoire nommé Hubs dans la racine du projet SignalRWebPack/ pour stocker le hub SignalR.
Créez un hub
Hubs/ChatHub.csavec le code suivant :using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRWebPack.Hubs { public class ChatHub : Hub { } }Ajoutez l’instruction
usingsuivante en haut du fichierStartup.cspour résoudre la référenceChatHub:using SignalRWebPack.Hubs;
Activer la communication entre le client et le serveur
L’application affiche actuellement un formulaire de base pour envoyer des messages, mais n’est pas encore fonctionnelle. Le serveur écoute une route spécifique, mais ne fait rien avec les messages envoyés.
Exécutez la commande suivante à la racine du projet :
npm i @microsoft/signalr @types/nodeLa commande précédente active :
- Le SignalRclient TypeScript, ce qui permet au client d’envoyer des messages au serveur.
- Les définitions de types TypeScript pour Node.js, qui permettent la vérification au moment de la compilation des types Node.js.
Ajoutez le code mis en surbrillance au fichier
src/index.ts:import "./css/main.css"; import * as signalR from "@microsoft/signalr"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { let m = document.createElement("div"); const author = document.createElement("div"); author.className = "message-author"; author.textContent = username; const content = document.createElement("div"); content.textContent = message; m.append(author, content); divMessages.appendChild(m); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch(err => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.key === "Enter") { send(); } }); btnSend.addEventListener("click", send); function send() { }Le code précédent prend en charge la réception de messages du serveur. La classe
HubConnectionBuildercrée un générateur pour configurer la connexion de serveur. La fonctionwithUrlconfigure l’URL du hub.SignalR permet l’échange de messages entre un client et un serveur. Chaque message a un nom spécifique. Par exemple, les messages portant le nom
messageReceivedpeuvent exécuter la logique responsable de l’affichage du nouveau message dans la zone de messages. L’écoute d’un message spécifique peut être effectuée au moyen de la fonctionon. N’importe quel nombre de noms de messages peuvent être écoutés. Vous pouvez aussi passer des paramètres au message, comme le nom de l’auteur et le contenu du message reçu. Une fois que le client reçoit un message, un nouvel élémentdivest créé avec le nom de l'auteur et le contenu du message ajoutés en tant qu'éléments enfants à l'aide detextContent. Il est ajouté à l’élémentdivprincipal qui affiche les messages.Maintenant que le client peut recevoir un message, configurez-le pour en envoyer. Ajoutez le code mis en surbrillance au fichier
src/index.ts:import "./css/main.css"; import * as signalR from "@microsoft/signalr"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { let messages = document.createElement("div"); const author = document.createElement("div"); author.className = "message-author"; author.textContent = username; const content = document.createElement("div"); content.textContent = message; messages.append(author, content); divMessages.appendChild(messages); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch(err => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.key === "Enter") { send(); } }); btnSend.addEventListener("click", send); function send() { connection.send("newMessage", username, tbMessage.value) .then(() => tbMessage.value = ""); }L’envoi d’un message au moyen de la connexion WebSocket nécessite l’appel de la méthode
send. Le premier paramètre de la méthode est le nom du message. Les données du message se trouvent dans les autres paramètres. Dans cet exemple, un message identifié commenewMessageest envoyé au serveur. Le message se compose du nom d’utilisateur et de l’entrée de l’utilisateur dans une zone de texte. Si l’envoi réussit, la valeur de la zone de texte est effacée.Ajoutez la méthode
NewMessageà la classeChatHub:using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRWebPack.Hubs { public class ChatHub : Hub { public async Task NewMessage(long username, string message) { await Clients.All.SendAsync("messageReceived", username, message); } } }Le code précédent diffuse les messages reçus à tous les utilisateurs connectés, une fois que le serveur les reçoit. Vous n’avez pas besoin d’avoir recours à une méthode générique
onpour recevoir tous les messages. Une méthode nommée d'après le nom du message suffit.Dans cet exemple, le client TypeScript envoie un message identifié comme
newMessage. La méthode C#NewMessageattend les données envoyées par le client. Un appel est effectué pour SendAsync sur Clients.All. Les messages reçus sont envoyés à tous les clients connectés au hub.
Tester l'application
Vérifiez que l’application fonctionne avec les étapes suivantes.
Exécuter Webpack en mode de mise en production. Dans la fenêtre Console du Gestionnaire de package, exécutez la commande suivante à la racine du projet. Si vous ne vous trouvez pas à la racine du projet, tapez
cd SignalRWebPackavant d’entrer la commande.npm run releaseCette commande génère les ressources côté client à délivrer pendant l’exécution de l’application. Les ressources sont placées dans le dossier
wwwroot.Webpack a effectué les tâches suivantes :
- Vide le contenu du répertoire
wwwroot. - Converti le TypeScript en JavaScript dans un processus appelé transpilation.
- Troncation du code JavaScript généré pour réduire la taille de fichier dans un processus appelé minimisation.
- Copie des fichiers JavaScript, CSS et HTML traités à partir de
srcdans le répertoirewwwroot. - Injection des éléments suivants dans le fichier
wwwroot/index.html:- Balise
<link>, référençant le fichierwwwroot/main.<hash>.css. Cette balise est placée immédiatement avant la balise</head>de fermeture. - Balise
<script>, référençant le fichierwwwroot/main.<hash>.jsminifié. Cette balise est placée immédiatement après la balise de fermeture</title>.
- Balise
- Vide le contenu du répertoire
Sélectionnez Déboguer>Démarrer sans débogage pour lancer l’application dans un navigateur sans attacher le débogueur. Le fichier
wwwroot/index.htmlest disponible àhttp://localhost:<port_number>.Si vous obtenez des erreurs de compilation, essayez de fermer et de rouvrir la solution.
Ouvrez une autre instance de navigateur (n’importe quel navigateur). Copiez l’URL de la barre d’adresse.
Choisissez un navigateur, tapez quelque chose dans la zone de texte Message, puis cliquez sur le bouton Envoyer. Le nom unique de l’utilisateur et le message sont affichés instantanément dans les deux pages.
Ressources supplémentaires
Ce tutoriel montre comment utiliser Webpack dans une application web ASP.NET Core SignalR pour regrouper et générer un client écrit en TypeScript. Webpack permet aux développeurs de regrouper et générer les ressources côté client d’une application web.
Dans ce tutoriel, vous allez apprendre à :
- Structurer une application de démarrage ASP.NET Core SignalR
- Configurer le client TypeScript SignalR
- Configurer un pipeline de build à l’aide de Webpack
- Configurer le serveur SignalR
- Activer la communication entre le client et le serveur
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Prerequisites
- Visual Studio 2019 avec la charge de travail ASP.NET et développement web
- SDK .NET Core 2.2 ou version ultérieure
- Node.js avec npm
Créer l’application web ASP.NET Core
Configurez Visual Studio pour rechercher npm dans la variable d'environnement PATH. Par défaut, Visual Studio utilise la version de npm qu’il trouve dans son répertoire d’installation. Suivez ces instructions dans Visual Studio :
Accédez à Outils>Options>Projets et solutions>Gestion des packages web>Outils web externes.
Sélectionnez l’entrée $(PATH) dans la liste. Sélectionnez la flèche vers le haut pour déplacer l’entrée à la deuxième position de la liste.
La configuration de Visual Studio est terminée. Nous allons maintenant créer le projet.
- Utilisez l’option de menu Fichier>Nouveau>Projet et choisissez le modèle Application web ASP.NET Core.
- Nommez le projet *SignalRWebPack`, puis sélectionnez Créer.
- Sélectionnez .NET Core dans la liste déroulante du framework cible, puis ASP.NET Core 2.2 dans la liste déroulante du sélecteur de framework. Sélectionnez le modèle Vide, puis sélectionnez Créer.
Configurer Webpack et TypeScript
Les étapes suivantes configurent la conversion de TypeScript en JavaScript et le regroupement des ressources côté client.
Exécutez la commande suivante dans la racine du projet pour créer un fichier
package.json:npm init -yAjoutez la propriété mise en évidence au fichier
package.json:{ "name": "SignalRWebPack", "version": "1.0.0", "private": true, "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }La définition de la propriété
privatesurtrueempêche les avertissements d’installation de package à l’étape suivante.Installez les packages npm nécessaires. À partir de la racine du projet, exécutez la commande suivante :
npm install -D -E clean-webpack-plugin@1.0.1 css-loader@2.1.0 html-webpack-plugin@4.0.0-beta.5 mini-css-extract-plugin@0.5.0 ts-loader@5.3.3 typescript@3.3.3 webpack@4.29.3 webpack-cli@3.2.3Détails de commande à prendre en compte :
- Un numéro de version suit le signe
@pour chaque nom de package. npm installe ces versions de package spécifiques. - L’option
-Edésactive le comportement par défaut de npm consistant à écrire des opérateurs de plage de gestion sémantique des versions dans packagejson. Par exemple,"webpack": "4.29.3"peut être utilisé à la place de"webpack": "^4.29.3". Cette option empêche les mises à niveau involontaires vers des versions de package plus récentes.
Consultez la documentation npm-install pour plus de détails.
- Un numéro de version suit le signe
Remplacez la propriété
scriptsdu fichierpackage.jsonpar le code suivant :"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Explication des scripts :
-
build: Regroupe les ressources côté client en mode de développement et surveille les changements de fichier. L’observateur de fichiers entraîne la régénération du paquet chaque fois qu’un fichier de projet change. L'optionmodedésactive les optimisations de production, telles que le tree shaking et la minification. Utilisez uniquementbuilddans le développement. -
release: Regroupe les ressources côté client en mode de production. -
publish: Exécute le scriptreleasepour regrouper les ressources côté client en mode de production. La commande appelle la commande publish de CLI .NET pour publier l’application.
-
Créez un fichier nommé
*webpack.config.jsà la racine du projet avec le code suivant :const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const CleanWebpackPlugin = require("clean-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/index.ts", output: { path: path.resolve(__dirname, "wwwroot"), filename: "[name].[chunkhash].js", publicPath: "/" }, resolve: { extensions: [".js", ".ts"] }, module: { rules: [ { test: /\.ts$/, use: "ts-loader" }, { test: /\.css$/, use: [MiniCssExtractPlugin.loader, "css-loader"] } ] }, plugins: [ new CleanWebpackPlugin(["wwwroot/*"]), new HtmlWebpackPlugin({ template: "./src/index.html" }), new MiniCssExtractPlugin({ filename: "css/[name].[chunkhash].css" }) ] };Le fichier précédent configure la compilation Webpack. Détails de configuration à prendre en compte :
- La propriété
outputremplace la valeur par défaut dedist. Le paquet est plutôt émis dans le répertoirewwwroot. - Le tableau
resolve.extensionsinclut.jspour importer le code JavaScript du client SignalR.
- La propriété
Créez un répertoire src à la racine du projet pour stocker les ressources côté client du projet.
Créez
src/index.htmlavec le balisage suivant.<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>ASP.NET Core SignalR</title> </head> <body> <div id="divMessages" class="messages"> </div> <div class="input-zone"> <label id="lblMessage" for="tbMessage">Message:</label> <input id="tbMessage" class="input-zone-input" type="text" /> <button id="btnSend">Send</button> </div> </body> </html>Le code HTML précédent définit le balisage réutilisable de la page d’accueil.
Créez un répertoire src/css. Son objectif est de stocker les fichiers
.cssdu projet.Créez
src/css/main.cssavec le balisage suivant :*, *::before, *::after { box-sizing: border-box; } html, body { margin: 0; padding: 0; } .input-zone { align-items: center; display: flex; flex-direction: row; margin: 10px; } .input-zone-input { flex: 1; margin-right: 10px; } .message-author { font-weight: bold; } .messages { border: 1px solid #000; margin: 10px; max-height: 300px; min-height: 300px; overflow-y: auto; padding: 5px; }Le fichier
main.cssprécédent définit le style de l’application.Créez
src/tsconfig.jsonavec le JSON suivant :{ "compilerOptions": { "target": "es5" } }Le code précédent configure le compilateur TypeScript pour produire du code JavaScript compatible ECMAScript 5.
Créez
src/index.tsavec le code suivant :import "./css/main.css"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.keyCode === 13) { send(); } }); btnSend.addEventListener("click", send); function send() { }Le code TypeScript précédent récupère les références aux éléments DOM et joint deux gestionnaires d’événements :
-
keyup: Cet événement se déclenche quand l’utilisateur tape des données dans la zone de textetbMessage. La fonctionsendest appelée quand l’utilisateur appuie sur la touche Entrée. -
click: Cet événement se déclenche quand l’utilisateur clique sur le bouton Envoyer. La fonctionsendest appelée.
-
Configurer l’application ASP.NET Core
Le code fourni dans la méthode
Startup.Configureaffiche Hello World!. Remplacez l’appel de méthodeapp.Runpar des appels à UseDefaultFiles(IApplicationBuilder) et UseStaticFiles(IApplicationBuilder).app.UseDefaultFiles(); app.UseStaticFiles();Le code précédent permet au serveur de localiser et traiter le fichier
index.html, que l’utilisateur entre son URL complète ou l’URL racine de l’application web.Appelez AddSignalR dans
Startup.ConfigureServices. Il ajoute les services SignalR au projet.services.AddSignalR();Mappez une route /hub au hub
ChatHub. Ajoutez les lignes suivantes à la fin deStartup.Configure:app.UseSignalR(options => { options.MapHub<ChatHub>("/hub"); });Créez un répertoire Hubs à la racine du projet. Son objectif est de stocker le hub SignalR, qui est créé à l’étape suivante.
Créez un hub
Hubs/ChatHub.csavec le code suivant :using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRWebPack.Hubs { public class ChatHub : Hub { } }Ajoutez le code suivant en haut du fichier
Startup.cspour résoudre la référence deChatHub:using SignalRWebPack.Hubs;
Activer la communication entre le client et le serveur
Actuellement, l’application affiche un formulaire simple pour envoyer des messages. Rien ne se produit quand vous essayez de le faire. Le serveur écoute une route spécifique, mais ne fait rien avec les messages envoyés.
Exécutez la commande suivante à la racine du projet :
npm install @aspnet/signalrLa commande précédente installe le client TypeScriptSignalR, ce qui permet au client d’envoyer des messages au serveur.
Ajoutez le code mis en surbrillance au fichier
src/index.ts:import "./css/main.css"; import * as signalR from "@aspnet/signalr"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { let m = document.createElement("div"); const author = document.createElement("div"); author.className = "message-author"; author.textContent = username; const content = document.createElement("div"); content.textContent = message; m.append(author, content); divMessages.appendChild(m); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch(err => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.keyCode === 13) { send(); } }); btnSend.addEventListener("click", send); function send() { }Le code précédent prend en charge la réception de messages du serveur. La classe
HubConnectionBuildercrée un générateur pour configurer la connexion de serveur. La fonctionwithUrlconfigure l’URL du hub.SignalR permet l’échange de messages entre un client et un serveur. Chaque message a un nom spécifique. Par exemple, les messages portant le nom
messageReceivedpeuvent exécuter la logique responsable de l’affichage du nouveau message dans la zone de messages. L’écoute d’un message spécifique peut être effectuée au moyen de la fonctionon. Vous pouvez écouter n’importe quel nombre de noms de message. Vous pouvez aussi passer des paramètres au message, comme le nom de l’auteur et le contenu du message reçu. Une fois que le client reçoit un message, un nouvel élémentdivest créé avec le nom de l'auteur et le contenu du message ajoutés en tant qu'éléments enfants à l'aide detextContent. Le nouveau message est ajouté à l’élément principaldivaffichant les messages.Maintenant que le client peut recevoir un message, configurez-le pour en envoyer. Ajoutez le code mis en surbrillance au fichier
src/index.ts:import "./css/main.css"; import * as signalR from "@aspnet/signalr"; const divMessages: HTMLDivElement = document.querySelector("#divMessages"); const tbMessage: HTMLInputElement = document.querySelector("#tbMessage"); const btnSend: HTMLButtonElement = document.querySelector("#btnSend"); const username = new Date().getTime(); const connection = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); connection.on("messageReceived", (username: string, message: string) => { let messageContainer = document.createElement("div"); const author = document.createElement("div"); author.className = "message-author"; author.textContent = username; const content = document.createElement("div"); content.textContent = message; messageContainer.append(author, content); divMessages.appendChild(messageContainer); divMessages.scrollTop = divMessages.scrollHeight; }); connection.start().catch(err => document.write(err)); tbMessage.addEventListener("keyup", (e: KeyboardEvent) => { if (e.keyCode === 13) { send(); } }); btnSend.addEventListener("click", send); function send() { connection.send("newMessage", username, tbMessage.value) .then(() => tbMessage.value = ""); }L’envoi d’un message au moyen de la connexion WebSocket nécessite l’appel de la méthode
send. Le premier paramètre de la méthode est le nom du message. Les données du message se trouvent dans les autres paramètres. Dans cet exemple, un message identifié commenewMessageest envoyé au serveur. Le message se compose du nom d’utilisateur et de l’entrée de l’utilisateur dans une zone de texte. Si l’envoi réussit, la valeur de la zone de texte est effacée.Ajoutez la méthode
NewMessageà la classeChatHub:using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRWebPack.Hubs { public class ChatHub : Hub { public async Task NewMessage(long username, string message) { await Clients.All.SendAsync("messageReceived", username, message); } } }Le code précédent diffuse les messages reçus à tous les utilisateurs connectés, une fois que le serveur les reçoit. Vous n’avez pas besoin d’avoir recours à une méthode générique
onpour recevoir tous les messages. Une méthode nommée d'après le nom du message suffit.Dans cet exemple, le client TypeScript envoie un message identifié comme
newMessage. La méthode C#NewMessageattend les données envoyées par le client. Un appel est effectué pour SendAsync sur Clients.All. Les messages reçus sont envoyés à tous les clients connectés au hub.
Tester l'application
Vérifiez que l’application fonctionne avec les étapes suivantes.
Exécuter Webpack en mode de mise en production. Dans la fenêtre Console du Gestionnaire de package, exécutez la commande suivante à la racine du projet. Si vous ne vous trouvez pas à la racine du projet, tapez
cd SignalRWebPackavant d’entrer la commande.npm run releaseCette commande génère les ressources côté client à délivrer pendant l’exécution de l’application. Les ressources sont placées dans le dossier
wwwroot.Webpack a effectué les tâches suivantes :
- Vide le contenu du répertoire
wwwroot. - Converti le TypeScript en JavaScript dans un processus appelé transpilation.
- Modifié le code JavaScript généré pour réduire la taille du fichier dans un processus appelé minification.
- Copie des fichiers JavaScript, CSS et HTML traités à partir de
srcdans le répertoirewwwroot. - Injection des éléments suivants dans le fichier
wwwroot/index.html:- Balise
<link>, référençant le fichierwwwroot/main.<hash>.css. Cette balise est placée immédiatement avant la balise</head>de fermeture. - Balise
<script>, référençant le fichierwwwroot/main.<hash>.jsminifié. Cette balise est placée immédiatement après la balise de fermeture</title>.
- Balise
- Vide le contenu du répertoire
Sélectionnez Déboguer>Démarrer sans débogage pour lancer l’application dans un navigateur sans attacher le débogueur. Le fichier
wwwroot/index.htmlest disponible àhttp://localhost:<port_number>.Ouvrez une autre instance de navigateur (n’importe quel navigateur). Copiez l’URL de la barre d’adresse.
Choisissez un navigateur, tapez quelque chose dans la zone de texte Message, puis cliquez sur le bouton Envoyer. Le nom unique de l’utilisateur et le message sont affichés instantanément dans les deux pages.