Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Note
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
Warning
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 10-Version dieses Artikels.
In diesem Tutorial wird veranschaulicht, wie Webpack in einer ASP.NET Core SignalR-Web-App verwendet wird, um einen in TypeScript geschriebenen Client zu bündeln und zu erstellen. Mit Webpack können Entwickler clientseitige Ressourcen einer Web-App bündeln und erstellen.
In diesem Tutorial lernen Sie Folgendes:
- Erstellen einer ASP.NET Core SignalR-App
- Konfigurieren des SignalR-Servers
- Konfigurieren einer Buildpipeline mithilfe von Webpack
- Konfigurieren des SignalR-TypeScript-Clients
- Kommunikation zwischen dem Client und dem Server herstellen
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Prerequisites
Die neueste Version von Visual Studio mit der Arbeitslast ASP.NET und Webentwicklung .
Erstellen einer ASP.NET Core-Web-App
Visual Studio verwendet standardmäßig die Version von NPM, die sich im Installationsverzeichnis befindet. So konfigurieren Sie Visual Studio, damit in der Umgebungsvariablen PATH nach npm gesucht wird:
Starten Sie die neueste Version von Visual Studio. Wählen Sie im Startfenster die Option Ohne Code fortfahren aus.
Navigieren Sie zu Extras>Optionen>Projekte und Lösungen>Webpaketverwaltung>Externe Webtools.
Wählen Sie in der Liste den Eintrag
$(PATH)aus. Drücken Sie die NACH-OBEN-TASTE, um den Eintrag auf die zweite Position in der Liste zu verschieben, und wählen Sie OK aus:
So erstellen Sie eine neue ASP.NET Core-Web-App:
- Verwenden Sie die Menüoption "Datei>Neu>Projekt/Lösung...".
- Wählen Sie im Dialogfeld " Neues Projekt erstellen " ASP.NET Vorlage "Core Empty " aus. Wählen Sie dann Weiter aus.
- Geben Sie im Dialogfeld "
SignalRWebpack" den Namen des Projekts ein. Wählen Sie Weiteraus. - Wählen Sie im Dialogfeld "Zusätzliche Informationen " die Option .NET 10.0 (Long Term Support) aus der Dropdownliste "Framework " aus. Wählen Sie "Erstellen" aus.
Fügen Sie das NuGet-Paket Microsoft.TypeScript.MSBuild zum Projekt hinzu:
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten, und wählen Sie "NuGet-Pakete verwalten" aus.
- Suchen Sie auf der Registerkarte Durchsuchen nach
Microsoft.TypeScript.MSBuild, und wählen Sie dann rechts Installieren aus, um das Paket zu installieren. - Wählen Sie im Dialogfeld Vorschau der Änderungen die Option Anwenden aus.
- Klicken im Dialogfeld Zustimmung zur Lizenz auf Ich stimme zu.
Visual Studio fügt das NuGet-Paket unter dem Knoten Abhängigkeiten im Projektmappen-Explorer hinzu, wodurch die TypeScript-Kompilierung im Projekt aktiviert wird.
Konfigurieren des Servers
In diesem Abschnitt konfigurieren Sie die ASP.NET Core-Web-App zum Senden und Empfangen von SignalR-Nachrichten.
Rufen Sie AddSignalR in
Program.csauf:var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Rufen Sie in
Program.csnun UseDefaultFiles und UseStaticFiles auf:var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Der vorherige Code ermöglicht dem Server, die
index.html-Datei zu finden und bereitzustellen. Die Datei wird bereitgestellt, wenn der Benutzer die vollständige URL oder nur die Stamm-URL der Web-App eingibt.Erstellen Sie im Projektstamm
Hubsein neues Verzeichnis namensSignalRWebpack/für die SignalR-Hubklasse.Erstellen Sie die neue Datei
Hubs/ChatHub.csmit dem folgenden Code: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); }Der vorangehende Code überträgt die empfangenen Nachrichten an alle verbundenen Benutzer, sobald der Server sie empfängt. Es ist nicht notwendig, eine generische
on-Methode zum Empfangen aller Nachrichten zu verwenden. Eine Methode mit dem gleichen Namen wie die Nachricht genügt.In diesem Beispiel:
- Der TypeScript-Client sendet eine Nachricht, die als
newMessageerkannt wurde. - Die C#-Methode
NewMessageerwartet die vom Client gesendeten Daten. - Es erfolgt ein Aufruf über SendAsync bei Clients.All.
- Die empfangenen Nachrichten werden an alle mit dem Hub verbundenen Clients gesendet.
- Der TypeScript-Client sendet eine Nachricht, die als
Fügen Sie die folgende
using-Anweisung am Anfang vonProgram.csein, um denChatHub-Verweis aufzulösen:using SignalRWebpack.Hubs;Ordnen Sie in
Program.csdie Route/hubdem HubChatHubzu. Ersetzen Sie den Code, derHallo Welt!anzeigt, durch den folgenden Code:app.MapHub<ChatHub>("/hub");
Konfigurieren des Clients
In diesem Abschnitt erstellen Sie ein Node.js Projekt zum Konvertieren von TypeScript in JavaScript und bündeln clientseitige Ressourcen, einschließlich HTML und CSS, mithilfe von Webpack.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json-Datei zu erstellen:npm init -yFügen Sie der
package.json-Datei die hervorgehobene Eigenschaft hinzu, und speichern Sie die Dateiänderungen:{ "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" } }Durch Festlegen der Eigenschaft
privateauftruewerden Warnungen bei der Paketinstallation im nächsten Schritt verhindert.Installieren Sie die erforderlichen NPM-Pakete. Führen Sie den folgenden Befehl über den Projektstamm aus:
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliDie Option
-Edeaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionsverwaltung in die Dateipackage.jsonschreibt. Beispielsweise wird"webpack": "5.76.1"anstelle von"webpack": "^5.76.1"verwendet. Diese Option verhindert unbeabsichtigte Upgrades auf neuere Paketversionen.Weitere Informationen finden Sie in der Dokumentation zu npm-install.
Ersetzen Sie die
scripts-Eigenschaft der Dateipackage.jsondurch den folgenden Code:"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Die folgenden Skripts sind definiert:
-
build: Bündelt die clientseitigen Ressourcen im Entwicklungsmodus und prüft auf Änderungen an Dateien. Der Dateiwatcher generiert das Bündel jedes Mal neu, wenn eine Änderung an einer Projektdatei vorgenommen wird. Die Optionmodedeaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuildnur bei der Entwicklung. -
release: Bündelt clientseitige Ressourcen im Produktionsmodus -
publish: Führt dasrelease-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET-CLI auf, um die App zu veröffentlichen.
-
Erstellen Sie eine Datei namens
webpack.config.jsim Projektstamm mit dem folgenden Code: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", }), ], };Die vorangehende Datei konfiguriert den Webpack-Kompilierungsvorgang:
- Die Eigenschaft
outputüberschreibt den Standardwert vondist. Das Bundle wird stattdessen an das Verzeichniswwwrootausgegeben. - Das
resolve.extensions-Array schließt.jsein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Erstellen Sie ein neues Verzeichnis namens
srcim Projektstamm (SignalRWebpack/) für den Clientcode.Kopieren Sie das Verzeichnis
srcund dessen Inhalt aus dem Beispielprojekt in den Projektstamm. Das Verzeichnissrcenthält die folgenden Dateien:index.html, die die Markup-Codebausteine für die Homepage definiert:<!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, die CSS-Stile für die Homepage bereitstellt:*, *::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, die den TypeScript-Compiler dafür konfiguriert, JavaScript-Code zu generieren, der mit ECMAScript 5 kompatibel ist:{ "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 = "")); }Der vorangehende Code ruft Verweise auf DOM-Elemente ab und fügt zwei Ereignishandler an:
-
keyup: Wird ausgelöst, wenn der*die Benutzer*in eine Eingabe im TextfeldtbMessagemacht. Die Funktionsendwird aufgerufen, wenn der*die Benutzer*in die EINGABETASTE drückt. -
click: Wird ausgelöst, wenn der*die Benutzer*in die Schaltfläche Senden auswählt und die Funktionsendaufgerufen wird.
Die Klasse
HubConnectionBuildererstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrlkonfiguriert die Hub-URL.Mit SignalR wird der Austausch von Nachrichten zwischen einem Client und einem Server ermöglicht. Jede Nachricht verfügt über einen spezifischen Namen. Beispielsweise können Nachrichten mit dem Namen
messageReceiveddie Logik zum Anzeigen neuer Nachrichten im Nachrichtenbereich ausführen. Mit deron-Funktion kann eine spezifische Nachricht belauscht werden. Sie können auf eine beliebige Anzahl von Nachrichtennamen lauschen. Außerdem können Parameter an die Nachricht übergeben werden, z.B. der Name des Autors und der Inhalt der empfangenen Nachricht. Sobald der Client eine Nachricht empfängt, wird ein neuesdivElement erstellt, bei dem der Name und der Nachrichteninhalt des Autors als untergeordnete Elemente mithilfe vontextContentangefügt werden. Es wird dem Hauptelementdivhinzugefügt, das die Nachrichten anzeigt.Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
senderforderlich. Der erste Parameter der Methode ist der Name der Nachricht. Die Nachrichtendaten befinden sich in den anderen Parametern. In diesem Beispiel wird eine Nachricht, die alsnewMessageerkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Eingabe des Benutzers aus einem Textfeld. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.-
Führen Sie den folgenden Befehl auf der Ebene des Projektstamms aus:
npm i @microsoft/signalr @types/nodeDer vorherige Befehl installiert Folgendes:
- Der SignalR-TypeScript-Client, mit dem der Client Nachrichten an den Server senden kann.
- Die TypeScript-Typdefinitionen für Node.js, die die Überprüfung zur Kompilierzeit von Node.js-Typen ermöglichen
Testen der App
Mit den folgenden Schritten können Sie überprüfen, ob die App funktioniert:
Führen Sie Webpack im
release-Modus aus. Führen Sie im Fenster der Paket-Manager-Konsole den folgenden Befehl im Projekt-Root aus.npm run releaseDieser Befehl generiert die clientseitigen Ressourcen, die zur Verfügung gestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwrootgespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwrootwurden bereinigt. - TypeScript wurde in JavaScript konvertiert. Dieser Prozess ist als Transpilierung bekannt.
- Der generierte JavaScript-Code wurde gekürzt, um die Dateigröße zu reduzieren. Dieser Prozess ist als Minimierung bekannt.
- Die verarbeiteten JavaScript-, CSS- und HTML-Dateien wurden aus
srcin das Verzeichniswwwrootkopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.htmleingefügt:- Ein
<link>-Tag, das auf diewwwroot/main.<hash>.css-Datei verweist Dieses Tag wird unmittelbar vor dem schließenden Tag</head>platziert. - Ein
<script>-Tag, das auf die verkleinertewwwroot/main.<hash>.js-Datei verweist Dieses Tag wird unmittelbar nach dem schließenden</title>-Tag eingefügt.
- Ein
- Die Inhalte des Verzeichnis
Klicken Sie auf Debuggen>Starten ohne Debugging, um die App in einem Browser zu starten, ohne den Debugger anzufügen. Die Datei
wwwroot/index.htmlwird unterhttps://localhost:<port>bereitgestellt.Wenn Kompilierungsfehler auftreten, versuchen Sie, die Projektmappe zu schließen und erneut zu öffnen.
Öffnen Sie eine andere Instanz eines beliebigen Browsers, und fügen Sie die URL in die Adressleiste ein.
Wählen Sie einen beliebigen Browser aus, geben Sie etwas im Textfeld Nachricht ein, und wählen Sie Senden aus. Der eindeutige Benutzername und die Nachricht werden sofort auf beiden Seiten angezeigt.
Nächste Schritte
- Stark typisierte Hubs
- Authentifizierung und Autorisierung in ASP.NET CoreSignalR
- MessagePack Hub Protocol in SignalR für ASP.NET Core
Weitere Ressourcen
In diesem Tutorial wird veranschaulicht, wie Webpack in einer ASP.NET Core SignalR-Web-App verwendet wird, um einen in TypeScript geschriebenen Client zu bündeln und zu erstellen. Mit Webpack können Entwickler clientseitige Ressourcen einer Web-App bündeln und erstellen.
In diesem Tutorial lernen Sie Folgendes:
- Erstellen einer ASP.NET Core SignalR-App
- Konfigurieren des SignalR-Servers
- Konfigurieren einer Buildpipeline mithilfe von Webpack
- Konfigurieren des SignalR-TypeScript-Clients
- Kommunikation zwischen dem Client und dem Server herstellen
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Prerequisites
Visual Studio 2022 mit der Arbeitslast ASP.NET und Webentwicklung
Erstellen einer ASP.NET Core-Web-App
Visual Studio verwendet standardmäßig die Version von NPM, die sich im Installationsverzeichnis befindet. So konfigurieren Sie Visual Studio, damit in der Umgebungsvariablen PATH nach npm gesucht wird:
Starten Sie Visual Studio. Wählen Sie im Startfenster die Option Ohne Code fortfahren aus.
Navigieren Sie zu Extras>Optionen>Projekte und Lösungen>Webpaketverwaltung>Externe Webtools.
Wählen Sie in der Liste den Eintrag
$(PATH)aus. Drücken Sie die NACH-OBEN-TASTE, um den Eintrag auf die zweite Position in der Liste zu verschieben, und wählen Sie OK aus:
.
So erstellen Sie eine neue ASP.NET Core-Web-App:
- Verwenden Sie die Menüoption Datei>Neu>Projekt, und wählen Sie die Vorlage ASP.NET Core (leer) aus. Wählen Sie Weiteraus.
- Geben Sie dem Projekt den Namen
SignalRWebpack, und wählen Sie Erstellen aus. - Wählen Sie .NET 8.0 (Langfristiger Support) aus der Dropdownliste Framework aus. Wählen Sie "Erstellen" aus.
Fügen Sie das NuGet-Paket Microsoft.TypeScript.MSBuild zum Projekt hinzu:
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten, und wählen Sie NuGet-Pakete verwalten aus. Suchen Sie auf der Registerkarte Durchsuchen nach
Microsoft.TypeScript.MSBuild, und wählen Sie dann rechts Installieren aus, um das Paket zu installieren.
Visual Studio fügt das NuGet-Paket unter dem Knoten Abhängigkeiten im Projektmappen-Explorer hinzu, wodurch die TypeScript-Kompilierung im Projekt aktiviert wird.
Konfigurieren des Servers
In diesem Abschnitt konfigurieren Sie die ASP.NET Core-Web-App zum Senden und Empfangen von SignalR-Nachrichten.
Rufen Sie AddSignalR in
Program.csauf:var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Rufen Sie in
Program.csnun UseDefaultFiles und UseStaticFiles auf:var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Der vorherige Code ermöglicht dem Server, die
index.html-Datei zu finden und bereitzustellen. Die Datei wird bereitgestellt, wenn der Benutzer die vollständige URL oder nur die Stamm-URL der Web-App eingibt.Erstellen Sie im Projektstamm
Hubsein neues Verzeichnis namensSignalRWebpack/für die SignalR-Hubklasse.Erstellen Sie die neue Datei
Hubs/ChatHub.csmit dem folgenden Code: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); }Der vorangehende Code überträgt die empfangenen Nachrichten an alle verbundenen Benutzer, sobald der Server sie empfängt. Es ist nicht notwendig, eine generische
on-Methode zum Empfangen aller Nachrichten zu verwenden. Eine Methode mit dem gleichen Namen wie die Nachricht genügt.In diesem Beispiel:
- Der TypeScript-Client sendet eine Nachricht, die als
newMessageerkannt wurde. - Die C#-Methode
NewMessageerwartet die vom Client gesendeten Daten. - Es erfolgt ein Aufruf über SendAsync bei Clients.All.
- Die empfangenen Nachrichten werden an alle mit dem Hub verbundenen Clients gesendet.
- Der TypeScript-Client sendet eine Nachricht, die als
Fügen Sie die folgende
using-Anweisung am Anfang vonProgram.csein, um denChatHub-Verweis aufzulösen:using SignalRWebpack.Hubs;Ordnen Sie in
Program.csdie Route/hubdem HubChatHubzu. Ersetzen Sie den Code, derHallo Welt!anzeigt, durch den folgenden Code:app.MapHub<ChatHub>("/hub");
Konfigurieren des Clients
In diesem Abschnitt erstellen Sie ein Node.js Projekt zum Konvertieren von TypeScript in JavaScript und bündeln clientseitige Ressourcen, einschließlich HTML und CSS, mithilfe von Webpack.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json-Datei zu erstellen:npm init -yFügen Sie der
package.json-Datei die hervorgehobene Eigenschaft hinzu, und speichern Sie die Dateiänderungen:{ "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" }Durch Festlegen der Eigenschaft
privateauftruewerden Warnungen bei der Paketinstallation im nächsten Schritt verhindert.Installieren Sie die erforderlichen NPM-Pakete. Führen Sie den folgenden Befehl über den Projektstamm aus:
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliDie Option
-Edeaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionsverwaltung in die Dateipackage.jsonschreibt. Beispielsweise wird"webpack": "5.76.1"anstelle von"webpack": "^5.76.1"verwendet. Diese Option verhindert unbeabsichtigte Upgrades auf neuere Paketversionen.Weitere Informationen finden Sie in der Dokumentation zu npm-install.
Ersetzen Sie die
scripts-Eigenschaft der Dateipackage.jsondurch den folgenden Code:"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Die folgenden Skripts sind definiert:
-
build: Bündelt die clientseitigen Ressourcen im Entwicklungsmodus und prüft auf Änderungen an Dateien. Der Dateiwatcher generiert das Bündel jedes Mal neu, wenn eine Änderung an einer Projektdatei vorgenommen wird. Die Optionmodedeaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuildnur bei der Entwicklung. -
release: Bündelt clientseitige Ressourcen im Produktionsmodus -
publish: Führt dasrelease-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET-CLI auf, um die App zu veröffentlichen.
-
Erstellen Sie eine Datei namens
webpack.config.jsim Projektstamm mit dem folgenden Code: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", }), ], };Die vorangehende Datei konfiguriert den Webpack-Kompilierungsvorgang:
- Die Eigenschaft
outputüberschreibt den Standardwert vondist. Das Bundle wird stattdessen an das Verzeichniswwwrootausgegeben. - Das
resolve.extensions-Array schließt.jsein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Erstellen Sie ein neues Verzeichnis namens
srcim Projektstamm (SignalRWebpack/) für den Clientcode.Kopieren Sie das Verzeichnis
srcund dessen Inhalt aus dem Beispielprojekt in den Projektstamm. Das Verzeichnissrcenthält die folgenden Dateien:index.html, die die Markup-Codebausteine für die Homepage definiert:<!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, die CSS-Stile für die Homepage bereitstellt:*, *::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, die den TypeScript-Compiler dafür konfiguriert, JavaScript-Code zu generieren, der mit ECMAScript 5 kompatibel ist:{ "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 = "")); }Der vorangehende Code ruft Verweise auf DOM-Elemente ab und fügt zwei Ereignishandler an:
-
keyup: Wird ausgelöst, wenn der*die Benutzer*in eine Eingabe im TextfeldtbMessagemacht. Die Funktionsendwird aufgerufen, wenn der*die Benutzer*in die EINGABETASTE drückt. -
click: Wird ausgelöst, wenn der*die Benutzer*in die Schaltfläche Senden auswählt und die Funktionsendaufgerufen wird.
Die Klasse
HubConnectionBuildererstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrlkonfiguriert die Hub-URL.Mit SignalR wird der Austausch von Nachrichten zwischen einem Client und einem Server ermöglicht. Jede Nachricht verfügt über einen spezifischen Namen. Beispielsweise können Nachrichten mit dem Namen
messageReceiveddie Logik zum Anzeigen neuer Nachrichten im Nachrichtenbereich ausführen. Mit deron-Funktion kann eine spezifische Nachricht belauscht werden. Sie können auf eine beliebige Anzahl von Nachrichtennamen lauschen. Außerdem können Parameter an die Nachricht übergeben werden, z.B. der Name des Autors und der Inhalt der empfangenen Nachricht. Sobald der Client eine Nachricht empfängt, wird ein neuesdivElement erstellt, bei dem der Name und der Nachrichteninhalt des Autors als untergeordnete Elemente mithilfe vontextContentangefügt werden. Es wird dem Hauptelementdivhinzugefügt, das die Nachrichten anzeigt.Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
senderforderlich. Der erste Parameter der Methode ist der Name der Nachricht. Die Nachrichtendaten befinden sich in den anderen Parametern. In diesem Beispiel wird eine Nachricht, die alsnewMessageerkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Eingabe des Benutzers aus einem Textfeld. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.-
Führen Sie den folgenden Befehl auf der Ebene des Projektstamms aus:
npm i @microsoft/signalr @types/nodeDer vorherige Befehl installiert Folgendes:
- Der SignalR-TypeScript-Client, mit dem der Client Nachrichten an den Server senden kann.
- Die TypeScript-Typdefinitionen für Node.js, die die Überprüfung zur Kompilierzeit von Node.js-Typen ermöglichen
Testen der App
Mit den folgenden Schritten können Sie überprüfen, ob die App funktioniert:
Führen Sie Webpack im
release-Modus aus. Führen Sie im Fenster der Paket-Manager-Konsole den folgenden Befehl im Projekt-Root aus.npm run releaseDieser Befehl generiert die clientseitigen Ressourcen, die zur Verfügung gestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwrootgespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwrootwurden bereinigt. - TypeScript wurde in JavaScript konvertiert. Dieser Prozess ist als Transpilierung bekannt.
- Der generierte JavaScript-Code wurde gekürzt, um die Dateigröße zu reduzieren. Dieser Prozess ist als Minimierung bekannt.
- Die verarbeiteten JavaScript-, CSS- und HTML-Dateien wurden aus
srcin das Verzeichniswwwrootkopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.htmleingefügt:- Ein
<link>-Tag, das auf diewwwroot/main.<hash>.css-Datei verweist Dieses Tag wird unmittelbar vor dem schließenden Tag</head>platziert. - Ein
<script>-Tag, das auf die verkleinertewwwroot/main.<hash>.js-Datei verweist Dieses Tag wird unmittelbar nach dem schließenden</title>-Tag eingefügt.
- Ein
- Die Inhalte des Verzeichnis
Klicken Sie auf Debuggen>Starten ohne Debugging, um die App in einem Browser zu starten, ohne den Debugger anzufügen. Die Datei
wwwroot/index.htmlwird unterhttps://localhost:<port>bereitgestellt.Wenn Kompilierungsfehler auftreten, versuchen Sie, die Projektmappe zu schließen und erneut zu öffnen.
Öffnen Sie eine andere Instanz eines beliebigen Browsers, und fügen Sie die URL in die Adressleiste ein.
Wählen Sie einen beliebigen Browser aus, geben Sie etwas im Textfeld Nachricht ein, und wählen Sie Senden aus. Der eindeutige Benutzername und die Nachricht werden sofort auf beiden Seiten angezeigt.
Nächste Schritte
- Stark typisierte Hubs
- Authentifizierung und Autorisierung in ASP.NET CoreSignalR
- MessagePack Hub Protocol in SignalR für ASP.NET Core
Weitere Ressourcen
In diesem Tutorial wird veranschaulicht, wie Webpack in einer ASP.NET Core SignalR-Web-App verwendet wird, um einen in TypeScript geschriebenen Client zu bündeln und zu erstellen. Mit Webpack können Entwickler clientseitige Ressourcen einer Web-App bündeln und erstellen.
In diesem Tutorial lernen Sie Folgendes:
- Erstellen einer ASP.NET Core SignalR-App
- Konfigurieren des SignalR-Servers
- Konfigurieren einer Buildpipeline mithilfe von Webpack
- Konfigurieren des SignalR-TypeScript-Clients
- Kommunikation zwischen dem Client und dem Server herstellen
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Prerequisites
Visual Studio 2022 mit der Arbeitslast ASP.NET und Webentwicklung
Erstellen einer ASP.NET Core-Web-App
Visual Studio verwendet standardmäßig die Version von NPM, die sich im Installationsverzeichnis befindet. So konfigurieren Sie Visual Studio, damit in der Umgebungsvariablen PATH nach npm gesucht wird:
Starten Sie Visual Studio. Wählen Sie im Startfenster die Option Ohne Code fortfahren aus.
Navigieren Sie zu Extras>Optionen>Projekte und Lösungen>Webpaketverwaltung>Externe Webtools.
Wählen Sie in der Liste den Eintrag
$(PATH)aus. Drücken Sie die NACH-OBEN-TASTE, um den Eintrag auf die zweite Position in der Liste zu verschieben, und wählen Sie OK aus:
.
So erstellen Sie eine neue ASP.NET Core-Web-App:
- Verwenden Sie die Menüoption Datei>Neu>Projekt, und wählen Sie die Vorlage ASP.NET Core (leer) aus. Wählen Sie Weiteraus.
- Geben Sie dem Projekt den Namen
SignalRWebpack, und wählen Sie Erstellen aus. - Wählen Sie .NET 7.0 (Standard Term Support) aus der Dropdownliste "Framework " aus. Wählen Sie "Erstellen" aus.
Fügen Sie das NuGet-Paket Microsoft.TypeScript.MSBuild zum Projekt hinzu:
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten, und wählen Sie NuGet-Pakete verwalten aus. Suchen Sie auf der Registerkarte Durchsuchen nach
Microsoft.TypeScript.MSBuild, und wählen Sie dann rechts Installieren aus, um das Paket zu installieren.
Visual Studio fügt das NuGet-Paket unter dem Knoten Abhängigkeiten im Projektmappen-Explorer hinzu, wodurch die TypeScript-Kompilierung im Projekt aktiviert wird.
Konfigurieren des Servers
In diesem Abschnitt konfigurieren Sie die ASP.NET Core-Web-App zum Senden und Empfangen von SignalR-Nachrichten.
Rufen Sie AddSignalR in
Program.csauf:var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Rufen Sie in
Program.csnun UseDefaultFiles und UseStaticFiles auf:var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Der vorherige Code ermöglicht dem Server, die
index.html-Datei zu finden und bereitzustellen. Die Datei wird bereitgestellt, wenn der Benutzer die vollständige URL oder nur die Stamm-URL der Web-App eingibt.Erstellen Sie im Projektstamm
Hubsein neues Verzeichnis namensSignalRWebpack/für die SignalR-Hubklasse.Erstellen Sie die neue Datei
Hubs/ChatHub.csmit dem folgenden Code: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); }Der vorangehende Code überträgt die empfangenen Nachrichten an alle verbundenen Benutzer, sobald der Server sie empfängt. Es ist nicht notwendig, eine generische
on-Methode zum Empfangen aller Nachrichten zu verwenden. Eine Methode mit dem gleichen Namen wie die Nachricht genügt.In diesem Beispiel:
- Der TypeScript-Client sendet eine Nachricht, die als
newMessageerkannt wurde. - Die C#-Methode
NewMessageerwartet die vom Client gesendeten Daten. - Es erfolgt ein Aufruf über SendAsync bei Clients.All.
- Die empfangenen Nachrichten werden an alle mit dem Hub verbundenen Clients gesendet.
- Der TypeScript-Client sendet eine Nachricht, die als
Fügen Sie die folgende
using-Anweisung am Anfang vonProgram.csein, um denChatHub-Verweis aufzulösen:using SignalRWebpack.Hubs;Ordnen Sie in
Program.csdie Route/hubdem HubChatHubzu. Ersetzen Sie den Code, derHallo Welt!anzeigt, durch den folgenden Code:app.MapHub<ChatHub>("/hub");
Konfigurieren des Clients
In diesem Abschnitt erstellen Sie ein Node.js Projekt zum Konvertieren von TypeScript in JavaScript und bündeln clientseitige Ressourcen, einschließlich HTML und CSS, mithilfe von Webpack.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json-Datei zu erstellen:npm init -yFügen Sie der
package.json-Datei die hervorgehobene Eigenschaft hinzu, und speichern Sie die Dateiänderungen:{ "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" }Durch Festlegen der Eigenschaft
privateauftruewerden Warnungen bei der Paketinstallation im nächsten Schritt verhindert.Installieren Sie die erforderlichen NPM-Pakete. Führen Sie den folgenden Befehl über den Projektstamm aus:
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliDie Option
-Edeaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionsverwaltung in die Dateipackage.jsonschreibt. Beispielsweise wird"webpack": "5.76.1"anstelle von"webpack": "^5.76.1"verwendet. Diese Option verhindert unbeabsichtigte Upgrades auf neuere Paketversionen.Weitere Informationen finden Sie in der Dokumentation zu npm-install.
Ersetzen Sie die
scripts-Eigenschaft der Dateipackage.jsondurch den folgenden Code:"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Die folgenden Skripts sind definiert:
-
build: Bündelt die clientseitigen Ressourcen im Entwicklungsmodus und prüft auf Änderungen an Dateien. Der Dateiwatcher generiert das Bündel jedes Mal neu, wenn eine Änderung an einer Projektdatei vorgenommen wird. Die Optionmodedeaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuildnur bei der Entwicklung. -
release: Bündelt clientseitige Ressourcen im Produktionsmodus -
publish: Führt dasrelease-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET-CLI auf, um die App zu veröffentlichen.
-
Erstellen Sie eine Datei namens
webpack.config.jsim Projektstamm mit dem folgenden Code: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", }), ], };Die vorangehende Datei konfiguriert den Webpack-Kompilierungsvorgang:
- Die Eigenschaft
outputüberschreibt den Standardwert vondist. Das Bundle wird stattdessen an das Verzeichniswwwrootausgegeben. - Das
resolve.extensions-Array schließt.jsein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Kopieren Sie das Verzeichnis
srcund dessen Inhalt aus dem Beispielprojekt in den Projektstamm. Das Verzeichnissrcenthält die folgenden Dateien:index.html, die die Markup-Codebausteine für die Homepage definiert:<!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, die CSS-Stile für die Homepage bereitstellt:*, *::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, die den TypeScript-Compiler dafür konfiguriert, JavaScript-Code zu generieren, der mit ECMAScript 5 kompatibel ist:{ "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 = "")); }Der vorangehende Code ruft Verweise auf DOM-Elemente ab und fügt zwei Ereignishandler an:
-
keyup: Wird ausgelöst, wenn der*die Benutzer*in eine Eingabe im TextfeldtbMessagemacht. Die Funktionsendwird aufgerufen, wenn der*die Benutzer*in die EINGABETASTE drückt. -
click: Wird ausgelöst, wenn der*die Benutzer*in die Schaltfläche Senden auswählt und die Funktionsendaufgerufen wird.
Die Klasse
HubConnectionBuildererstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrlkonfiguriert die Hub-URL.Mit SignalR wird der Austausch von Nachrichten zwischen einem Client und einem Server ermöglicht. Jede Nachricht verfügt über einen spezifischen Namen. Beispielsweise können Nachrichten mit dem Namen
messageReceiveddie Logik zum Anzeigen neuer Nachrichten im Nachrichtenbereich ausführen. Mit deron-Funktion kann eine spezifische Nachricht belauscht werden. Sie können auf eine beliebige Anzahl von Nachrichtennamen lauschen. Außerdem können Parameter an die Nachricht übergeben werden, z.B. der Name des Autors und der Inhalt der empfangenen Nachricht. Sobald der Client eine Nachricht empfängt, wird ein neuesdivElement erstellt, bei dem der Name und der Nachrichteninhalt des Autors als untergeordnete Elemente mithilfe vontextContentangefügt werden. Es wird dem Hauptelementdivhinzugefügt, das die Nachrichten anzeigt.Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
senderforderlich. Der erste Parameter der Methode ist der Name der Nachricht. Die Nachrichtendaten befinden sich in den anderen Parametern. In diesem Beispiel wird eine Nachricht, die alsnewMessageerkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Eingabe des Benutzers aus einem Textfeld. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.-
Führen Sie den folgenden Befehl auf der Ebene des Projektstamms aus:
npm i @microsoft/signalr @types/nodeDer vorherige Befehl installiert Folgendes:
- Der SignalR-TypeScript-Client, mit dem der Client Nachrichten an den Server senden kann.
- Die TypeScript-Typdefinitionen für Node.js, die die Überprüfung zur Kompilierzeit von Node.js-Typen ermöglichen
Testen der App
Mit den folgenden Schritten können Sie überprüfen, ob die App funktioniert:
Führen Sie Webpack im
release-Modus aus. Führen Sie im Fenster der Paket-Manager-Konsole den folgenden Befehl im Projekt-Root aus.npm run releaseDieser Befehl generiert die clientseitigen Ressourcen, die zur Verfügung gestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwrootgespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwrootwurden bereinigt. - TypeScript wurde in JavaScript konvertiert. Dieser Prozess ist als Transpilierung bekannt.
- Der generierte JavaScript-Code wurde gekürzt, um die Dateigröße zu reduzieren. Dieser Prozess ist als Minimierung bekannt.
- Die verarbeiteten JavaScript-, CSS- und HTML-Dateien wurden aus
srcin das Verzeichniswwwrootkopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.htmleingefügt:- Ein
<link>-Tag, das auf diewwwroot/main.<hash>.css-Datei verweist Dieses Tag wird unmittelbar vor dem schließenden Tag</head>platziert. - Ein
<script>-Tag, das auf die verkleinertewwwroot/main.<hash>.js-Datei verweist Dieses Tag wird unmittelbar nach dem schließenden</title>-Tag eingefügt.
- Ein
- Die Inhalte des Verzeichnis
Klicken Sie auf Debuggen>Starten ohne Debugging, um die App in einem Browser zu starten, ohne den Debugger anzufügen. Die Datei
wwwroot/index.htmlwird unterhttps://localhost:<port>bereitgestellt.Wenn Kompilierungsfehler auftreten, versuchen Sie, die Projektmappe zu schließen und erneut zu öffnen.
Öffnen Sie eine andere Instanz eines beliebigen Browsers, und fügen Sie die URL in die Adressleiste ein.
Wählen Sie einen beliebigen Browser aus, geben Sie etwas im Textfeld Nachricht ein, und wählen Sie Senden aus. Der eindeutige Benutzername und die Nachricht werden sofort auf beiden Seiten angezeigt.
Nächste Schritte
- Stark typisierte Hubs
- Authentifizierung und Autorisierung in ASP.NET CoreSignalR
- MessagePack Hub Protocol in SignalR für ASP.NET Core
Weitere Ressourcen
In diesem Tutorial wird veranschaulicht, wie Webpack in einer ASP.NET Core SignalR-Web-App verwendet wird, um einen in TypeScript geschriebenen Client zu bündeln und zu erstellen. Mit Webpack können Entwickler clientseitige Ressourcen einer Web-App bündeln und erstellen.
In diesem Tutorial lernen Sie Folgendes:
- Erstellen einer ASP.NET Core SignalR-App
- Konfigurieren des SignalR-Servers
- Konfigurieren einer Buildpipeline mithilfe von Webpack
- Konfigurieren des SignalR-TypeScript-Clients
- Kommunikation zwischen dem Client und dem Server herstellen
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Prerequisites
- Visual Studio 2022 mit der Arbeitslast ASP.NET und Webentwicklung
- .NET 6 SDK
Erstellen einer ASP.NET Core-Web-App
Visual Studio verwendet standardmäßig die Version von NPM, die sich im Installationsverzeichnis befindet. So konfigurieren Sie Visual Studio, damit in der Umgebungsvariablen PATH nach npm gesucht wird:
Starten Sie Visual Studio. Wählen Sie im Startfenster die Option Ohne Code fortfahren aus.
Navigieren Sie zu Extras>Optionen>Projekte und Lösungen>Webpaketverwaltung>Externe Webtools.
Wählen Sie in der Liste den Eintrag
$(PATH)aus. Drücken Sie die NACH-OBEN-TASTE, um den Eintrag auf die zweite Position in der Liste zu verschieben, und wählen Sie OK aus:
.
So erstellen Sie eine neue ASP.NET Core-Web-App:
- Verwenden Sie die Menüoption Datei>Neu>Projekt, und wählen Sie die Vorlage ASP.NET Core (leer) aus. Wählen Sie Weiteraus.
- Geben Sie dem Projekt den Namen
SignalRWebpack, und wählen Sie Erstellen aus. - Wählen Sie .NET 6.0 (Long Term Support) aus der Dropdownliste "Framework " aus. Wählen Sie "Erstellen" aus.
Fügen Sie das NuGet-Paket Microsoft.TypeScript.MSBuild zum Projekt hinzu:
- Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten, und wählen Sie NuGet-Pakete verwalten aus. Suchen Sie auf der Registerkarte Durchsuchen nach
Microsoft.TypeScript.MSBuild, und wählen Sie dann rechts Installieren aus, um das Paket zu installieren.
Visual Studio fügt das NuGet-Paket unter dem Knoten Abhängigkeiten im Projektmappen-Explorer hinzu, wodurch die TypeScript-Kompilierung im Projekt aktiviert wird.
Konfigurieren des Servers
In diesem Abschnitt konfigurieren Sie die ASP.NET Core-Web-App zum Senden und Empfangen von SignalR-Nachrichten.
Rufen Sie AddSignalR in
Program.csauf:var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();Rufen Sie in
Program.csnun UseDefaultFiles und UseStaticFiles auf:var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles();Der vorherige Code ermöglicht dem Server, die
index.html-Datei zu finden und bereitzustellen. Die Datei wird bereitgestellt, wenn der Benutzer die vollständige URL oder nur die Stamm-URL der Web-App eingibt.Erstellen Sie im Projektstamm
Hubsein neues Verzeichnis namensSignalRWebpack/für die SignalR-Hubklasse.Erstellen Sie die neue Datei
Hubs/ChatHub.csmit dem folgenden Code: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); }Der vorangehende Code überträgt die empfangenen Nachrichten an alle verbundenen Benutzer, sobald der Server sie empfängt. Es ist nicht notwendig, eine generische
on-Methode zum Empfangen aller Nachrichten zu verwenden. Eine Methode mit dem gleichen Namen wie die Nachricht genügt.In diesem Beispiel sendet der TypeScript-Client eine Nachricht, die als
newMessageerkannt wurde. Die C#-MethodeNewMessageerwartet die vom Client gesendeten Daten. Es erfolgt ein Aufruf über SendAsync bei Clients.All. Die empfangenen Nachrichten werden an alle mit dem Hub verbundenen Clients gesendet.Fügen Sie die folgende
using-Anweisung am Anfang vonProgram.csein, um denChatHub-Verweis aufzulösen:using SignalRWebpack.Hubs;Ordnen Sie in
Program.csdie Route/hubdem HubChatHubzu. Ersetzen Sie den Code, derHallo Welt!anzeigt, durch den folgenden Code:app.MapHub<ChatHub>("/hub");
Konfigurieren des Clients
In diesem Abschnitt erstellen Sie ein Node.js Projekt zum Konvertieren von TypeScript in JavaScript und bündeln clientseitige Ressourcen, einschließlich HTML und CSS, mithilfe von Webpack.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json-Datei zu erstellen:npm init -yFügen Sie der
package.json-Datei die hervorgehobene Eigenschaft hinzu, und speichern Sie die Dateiänderungen:{ "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" }Durch Festlegen der Eigenschaft
privateauftruewerden Warnungen bei der Paketinstallation im nächsten Schritt verhindert.Installieren Sie die erforderlichen NPM-Pakete. Führen Sie den folgenden Befehl über den Projektstamm aus:
npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cliDie Option
-Edeaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionsverwaltung in die Dateipackage.jsonschreibt. Beispielsweise wird"webpack": "5.70.0"anstelle von"webpack": "^5.70.0"verwendet. Diese Option verhindert unbeabsichtigte Upgrades auf neuere Paketversionen.Weitere Informationen finden Sie in der Dokumentation zu npm-install.
Ersetzen Sie die
scripts-Eigenschaft der Dateipackage.jsondurch den folgenden Code:"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Die folgenden Skripts sind definiert:
-
build: Bündelt die clientseitigen Ressourcen im Entwicklungsmodus und prüft auf Änderungen an Dateien. Der Dateiwatcher generiert das Bündel jedes Mal neu, wenn eine Änderung an einer Projektdatei vorgenommen wird. Die Optionmodedeaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuildnur bei der Entwicklung. -
release: Bündelt clientseitige Ressourcen im Produktionsmodus -
publish: Führt dasrelease-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET-CLI auf, um die App zu veröffentlichen.
-
Erstellen Sie eine Datei namens
webpack.config.jsim Projektstamm mit dem folgenden Code: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", }), ], };Die vorangehende Datei konfiguriert den Webpack-Kompilierungsvorgang:
- Die Eigenschaft
outputüberschreibt den Standardwert vondist. Das Bundle wird stattdessen an das Verzeichniswwwrootausgegeben. - Das
resolve.extensions-Array schließt.jsein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Kopieren Sie das Verzeichnis
srcund dessen Inhalt aus dem Beispielprojekt in den Projektstamm. Das Verzeichnissrcenthält die folgenden Dateien:index.html, die die Markup-Codebausteine für die Homepage definiert:<!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, die CSS-Stile für die Homepage bereitstellt:*, *::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, die den TypeScript-Compiler dafür konfiguriert, JavaScript-Code zu generieren, der mit ECMAScript 5 kompatibel ist:{ "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 = "")); }
Der vorangehende Code ruft Verweise auf DOM-Elemente ab und fügt zwei Ereignishandler an:
-
keyup: Wird ausgelöst, wenn der*die Benutzer*in eine Eingabe im TextfeldtbMessagemacht. Die Funktionsendwird aufgerufen, wenn der*die Benutzer*in die EINGABETASTE drückt. -
click: Wird ausgelöst, wenn der*die Benutzer*in die Schaltfläche Senden auswählt und die Funktionsendaufgerufen wird.
Die Klasse
HubConnectionBuildererstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrlkonfiguriert die Hub-URL.Mit SignalR wird der Austausch von Nachrichten zwischen einem Client und einem Server ermöglicht. Jede Nachricht verfügt über einen spezifischen Namen. Beispielsweise können Nachrichten mit dem Namen
messageReceiveddie Logik zum Anzeigen neuer Nachrichten im Nachrichtenbereich ausführen. Mit deron-Funktion kann eine spezifische Nachricht belauscht werden. Sie können auf eine beliebige Anzahl von Nachrichtennamen lauschen. Außerdem können Parameter an die Nachricht übergeben werden, z.B. der Name des Autors und der Inhalt der empfangenen Nachricht. Sobald der Client eine Nachricht empfängt, wird ein neuesdivElement erstellt, bei dem der Name und der Nachrichteninhalt des Autors als untergeordnete Elemente mithilfe vontextContentangefügt werden. Es wird dem Hauptelementdivhinzugefügt, das die Nachrichten anzeigt.Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
senderforderlich. Der erste Parameter der Methode ist der Name der Nachricht. Die Nachrichtendaten befinden sich in den anderen Parametern. In diesem Beispiel wird eine Nachricht, die alsnewMessageerkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Eingabe des Benutzers aus einem Textfeld. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.Führen Sie den folgenden Befehl auf der Ebene des Projektstamms aus:
npm i @microsoft/signalr @types/nodeDer vorherige Befehl installiert Folgendes:
- Der SignalR-TypeScript-Client, mit dem der Client Nachrichten an den Server senden kann.
- Die TypeScript-Typdefinitionen für Node.js, die die Überprüfung zur Kompilierzeit von Node.js-Typen ermöglichen
Testen der App
Mit den folgenden Schritten können Sie überprüfen, ob die App funktioniert:
Führen Sie Webpack im
release-Modus aus. Führen Sie im Fenster der Paket-Manager-Konsole den folgenden Befehl im Projekt-Root aus. Wenn Sie sich nicht im Projektstammverzeichnis befinden, geben Siecd SignalRWebpackein, bevor Sie den Befehl eingeben.npm run releaseDieser Befehl generiert die clientseitigen Ressourcen, die zur Verfügung gestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwrootgespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwrootwurden bereinigt. - TypeScript wurde in JavaScript konvertiert. Dieser Prozess ist als Transpilierung bekannt.
- Der generierte JavaScript-Code wurde gekürzt, um die Dateigröße zu reduzieren. Dieser Prozess ist als Minimierung bekannt.
- Die verarbeiteten JavaScript-, CSS- und HTML-Dateien wurden aus
srcin das Verzeichniswwwrootkopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.htmleingefügt:- Ein
<link>-Tag, das auf diewwwroot/main.<hash>.css-Datei verweist Dieses Tag wird unmittelbar vor dem schließenden Tag</head>platziert. - Ein
<script>-Tag, das auf die verkleinertewwwroot/main.<hash>.js-Datei verweist Dieses Tag wird unmittelbar nach dem schließenden</title>-Tag eingefügt.
- Ein
- Die Inhalte des Verzeichnis
Klicken Sie auf Debuggen>Starten ohne Debugging, um die App in einem Browser zu starten, ohne den Debugger anzufügen. Die Datei
wwwroot/index.htmlwird unterhttps://localhost:<port>bereitgestellt.Wenn Sie Kompilierungsfehlermeldungen erhalten, versuchen Sie, die Projektmappe zu schließen und erneut zu öffnen.
Öffnen Sie eine andere Instanz eines beliebigen Browsers, und fügen Sie die URL in die Adressleiste ein.
Wählen Sie einen beliebigen Browser aus, geben Sie etwas im Textfeld Nachricht ein, und wählen Sie Senden aus. Der eindeutige Benutzername und die Nachricht werden sofort auf beiden Seiten angezeigt.
Nächste Schritte
- Stark typisierte Hubs
- Authentifizierung und Autorisierung in ASP.NET CoreSignalR
- MessagePack Hub Protocol in SignalR für ASP.NET Core
Weitere Ressourcen
In diesem Tutorial wird veranschaulicht, wie Webpack in einer ASP.NET Core SignalR-Web-App verwendet wird, um einen in TypeScript geschriebenen Client zu bündeln und zu erstellen. Mit Webpack können Entwickler clientseitige Ressourcen einer Web-App bündeln und erstellen.
In diesem Tutorial lernen Sie Folgendes:
- Aufbauen einer einfachen ASP.NET Core SignalR-App
- Konfigurieren des SignalR-TypeScript-Clients
- Konfigurieren einer Buildpipeline mithilfe von Webpack
- Konfigurieren des SignalR-Servers
- Aktivieren der Kommunikation zwischen Client und Server
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Prerequisites
- Visual Studio 2019 mit der Workload für ASP.NET und Webentwicklung
- .NET Core SDK 3.0 oder höher
- Node.js mit NPM
Erstellen einer ASP.NET Core-Web-App
Konfigurieren Sie Visual Studio, damit in der Umgebungsvariable PATH nach NPM gesucht wird. Visual Studio verwendet standardmäßig die Version von NPM, die sich im Installationsverzeichnis befindet. Führen Sie die folgenden Anweisungen in Visual Studio aus:
Starten Sie Visual Studio. Wählen Sie im Startfenster die Option Ohne Code fortfahren aus.
Navigieren Sie zu Extras>Optionen>Projekte und Lösungen>Webpaketverwaltung>Externe Webtools.
Wählen Sie in der Liste den Eintrag $(PATH) aus. Drücken Sie die NACH-OBEN-TASTE, um den Eintrag auf die zweite Position in der Liste zu verschieben, und wählen Sie OK aus.
.
Die Konfiguration von Visual Studio ist abgeschlossen.
- Verwenden Sie die Menüoption Datei>Neu>Projekt, und wählen Sie die Vorlage ASP.NET Core-Web-App aus. Wählen Sie Weiteraus.
- Nennen Sie das Projekt *SignalRWebPac`` und wählen Sie Erstellen aus.
- Wählen Sie in der Dropdownliste mit Zielframeworks .NET Core und in der Dropdownliste zur Auswahl des Frameworks ASP.NET Core 3.1 aus. Wählen Sie die leere Vorlage und dann Erstellen aus.
Microsoft.TypeScript.MSBuild-Paket zu Projekt hinzufügen:
- Klicken Sie im Projektmappen-Explorer (rechter Bereich) mit der rechten Maustaste auf den Projektknoten, und wählen Sie NuGet-Pakete verwalten aus. Suchen Sie auf der Registerkarte Durchsuchen nach
Microsoft.TypeScript.MSBuild, und klicken Sie dann rechts auf Installieren, um das Paket zu installieren.
Visual Studio fügt das NuGet-Paket unter dem Knoten Abhängigkeiten im Projektmappen-Explorer hinzu, wodurch die TypeScript-Kompilierung im Projekt aktiviert wird.
Konfigurieren von Webpack und TypeScript
In den folgenden Schritten wird die Konvertierung von TypeScript zu JavaScript und die Bündelung clientseitiger Ressourcen konfiguriert.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json-Datei zu erstellen:npm init -yFügen Sie der
package.json-Datei die hervorgehobene Eigenschaft hinzu, und speichern Sie die Dateiänderungen:{ "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" }Durch Festlegen der Eigenschaft
privateauftruewerden Warnungen bei der Paketinstallation im nächsten Schritt verhindert.Installieren Sie die erforderlichen NPM-Pakete. Führen Sie den folgenden Befehl über den Projektstamm aus:
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.10Beachten Sie die folgenden Befehlsdetails:
- Auf das
@-Zeichen folgt bei jedem Paketnamen eine Versionsnummer. Die spezifischen Paketversionen werden von NPM installiert. - Die Option
-Edeaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionierung in die Datei „*packagejson“ schreibt. Beispielsweise wird"webpack": "4.41.5"anstelle von"webpack": "^4.41.5"verwendet. Diese Option verhindert unbeabsichtigte Upgrades auf neuere Paketversionen.
Ausführliche Informationen finden Sie in der Dokumentation zu npm-install.
- Auf das
Ersetzen Sie die
scripts-Eigenschaft der Dateipackage.jsondurch den folgenden Code:"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Im Folgenden werden die Skripts erklärt:
-
build: Bündelt die clientseitigen Ressourcen im Entwicklungsmodus und prüft auf Änderungen an Dateien. Der Dateiwatcher generiert das Bündel jedes Mal neu, wenn eine Änderung an einer Projektdatei vorgenommen wird. Die Optionmodedeaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuildnur in der Entwicklung. -
release: Bündelt clientseitige Ressourcen im Produktionsmodus -
publish: Führt dasrelease-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET-CLI auf, um die App zu veröffentlichen.
-
Erstellen Sie eine Datei namens
webpack.config.jsim Projektstamm mit dem folgenden Code: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" }) ] };Die vorangehende Datei konfiguriert die Webpack-Kompilierung. Zu beachtende Konfigurationsdetails:
- Die Eigenschaft
outputüberschreibt den Standardwert vondist. Das Bundle wird stattdessen an das Verzeichniswwwrootausgegeben. - Das
resolve.extensions-Array schließt.jsein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Erstellen Sie ein neues src-Verzeichnis im Projektstamm, um die clientseitigen Ressourcen des Projekts zu speichern.
Erstellen Sie
src/index.htmlmit dem folgenden Markup.<!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>Der vorangehende HTML-Code definiert die Markupbausteine der Homepage.
Erstellen Sie ein neues src/css-Verzeichnis. Es dient als Speicherort für die
.css-Dateien des Projekts.Erstellen Sie
src/css/main.cssmit der folgenden CSS-Spezifikation:*, *::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; }Die vorangehende Datei
main.cssformatiert die App.Erstellen Sie
src/tsconfig.jsonmit dem folgenden JSON:{ "compilerOptions": { "target": "es5" } }Der vorangehende Code konfiguriert den TypeScript-Compiler, um JavaScript-Code zu erstellen, der mit ECMAScript 5 kompatibel ist.
Erstellen Sie
src/index.tsmit dem folgenden Code: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() { }Der vorangehende TypeScript-Code ruft Verweise auf DOM-Elemente ab und fügt zwei Ereignishandler an:
-
keyup: Dieses Ereignis wird ausgelöst, wenn der Benutzer etwas in dastbMessage-Textfeld eingibt. Die Funktionsendwird aufgerufen, wenn der Benutzer die EINGABETASTE drückt. -
click: Dieses Ereignis wird ausgelöst, wenn der*die Benutzer*in die Schaltfläche Senden auswählt. Die Funktionsendwird aufgerufen.
-
Konfigurieren der App
Fügen Sie in
Startup.ConfigureAufrufe zu UseDefaultFiles(IApplicationBuilder) und UseStaticFiles(IApplicationBuilder) hinzu.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"); }); }Der vorherige Code ermöglicht dem Server, die
index.html-Datei zu finden und bereitzustellen. Die Datei wird bereitgestellt, wenn der Benutzer die vollständige URL oder nur die Stamm-URL der Web-App eingibt.Ordnen Sie am Ende von
Startup.Configureeine /hub-Route demChatHub-Hub zu. Ersetzen Sie den Code, der Hallo Welt! anzeigt, durch die folgende Zeile:app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/hub"); });Rufen Sie AddSignalR in
Startup.ConfigureServicesauf.services.AddSignalR();Erstellen Sie im Projektstamm SignalRWebPack/ ein neues Verzeichnis namens Hubs, um den SignalR-Hub zu speichern.
Erstellen Sie mit dem folgenden Code den Hub
Hubs/ChatHub.cs:using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRWebPack.Hubs { public class ChatHub : Hub { } }Fügen Sie die folgende
using-Anweisung am Anfang der DateiStartup.csein, um denChatHub-Verweis aufzulösen:using SignalRWebPack.Hubs;
Aktivieren der Kommunikation zwischen Client und Server
Die App zeigt zurzeit ein Basisformular zum Senden von Nachrichten an, ist jedoch darüber hinaus nicht funktionsfähig. Der Server lauscht einer spezifischen Route, aber er verarbeitet gesendete Nachrichten nicht.
Führen Sie den folgenden Befehl auf der Ebene des Projektstamms aus:
npm i @microsoft/signalr @types/nodeDer vorherige Befehl installiert Folgendes:
- Der SignalR-TypeScript-Client, mit dem der Client Nachrichten an den Server senden kann.
- Die TypeScript-Typdefinitionen für Node.js, die die Überprüfung zur Kompilierzeit von Node.js-Typen ermöglichen
Fügen Sie der Datei
src/index.tsden folgenden hervorgehobenen Code hinzu: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() { }Der vorangehende Code unterstützt das Empfangen von Nachrichten vom Server. Die Klasse
HubConnectionBuildererstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrlkonfiguriert die Hub-URL.Mit SignalR wird der Austausch von Nachrichten zwischen einem Client und einem Server ermöglicht. Jede Nachricht verfügt über einen spezifischen Namen. Beispielsweise können Nachrichten mit dem Namen
messageReceiveddie Logik zum Anzeigen neuer Nachrichten im Nachrichtenbereich ausführen. Mit deron-Funktion kann eine spezifische Nachricht belauscht werden. Sie können auf eine beliebige Anzahl von Nachrichtennamen lauschen. Außerdem können Parameter an die Nachricht übergeben werden, z.B. der Name des Autors und der Inhalt der empfangenen Nachricht. Sobald der Client eine Nachricht empfängt, wird ein neuesdivElement erstellt, bei dem der Name und der Nachrichteninhalt des Autors als untergeordnete Elemente mithilfe vontextContentangefügt werden. Es wird dem Hauptelementdivhinzugefügt, das die Nachrichten anzeigt.Da der Client nun dazu in der Lage ist, Nachrichten zu empfangen, konfigurieren Sie ihn zum Senden von Nachrichten. Fügen Sie der Datei
src/index.tsden folgenden hervorgehobenen Code hinzu: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 = ""); }Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
senderforderlich. Der erste Parameter der Methode ist der Name der Nachricht. Die Nachrichtendaten befinden sich in den anderen Parametern. In diesem Beispiel wird eine Nachricht, die alsnewMessageerkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Eingabe des Benutzers aus einem Textfeld. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.Fügen Sie der Klasse
NewMessagedie MethodeChatHubhinzu: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); } } }Der vorangehende Code überträgt die empfangenen Nachrichten an alle verbundenen Benutzer, sobald der Server sie empfängt. Es ist nicht notwendig, eine generische
on-Methode zum Empfangen aller Nachrichten zu verwenden. Eine Methode benannt nach dem Namen der Nachricht genügt.In diesem Beispiel sendet der TypeScript-Client eine Nachricht, die als
newMessageerkannt wurde. Die C#-MethodeNewMessageerwartet die vom Client gesendeten Daten. Es erfolgt ein Aufruf über SendAsync bei Clients.All. Die empfangenen Nachrichten werden an alle mit dem Hub verbundenen Clients gesendet.
Testen der App
Mit den folgenden Schritten können Sie überprüfen, ob die App funktioniert.
Führen Sie Webpack im Releasemodus aus. Führen Sie im Fenster der Paket-Manager-Konsole den folgenden Befehl im Projekt-Root aus. Wenn Sie sich nicht im Projektstammverzeichnis befinden, geben Sie
cd SignalRWebPackein, bevor Sie den Befehl eingeben.npm run releaseDieser Befehl generiert die clientseitigen Ressourcen, die zur Verfügung gestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwrootgespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwrootwurden bereinigt. - TypeScript wurde in JavaScript konvertiert. Dieser Prozess ist als Transpilierung bekannt.
- Der generierte JavaScript-Code wurde gekürzt, um die Dateigröße zu reduzieren. Dieser Prozess ist als Minimierung bekannt.
- Die verarbeiteten JavaScript-, CSS- und HTML-Dateien wurden aus
srcin das Verzeichniswwwrootkopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.htmleingefügt:- Ein
<link>-Tag, das auf diewwwroot/main.<hash>.css-Datei verweist Dieses Tag wird unmittelbar vor dem schließenden Tag</head>platziert. - Ein
<script>-Tag, das auf die verkleinertewwwroot/main.<hash>.js-Datei verweist Dieses Tag wird unmittelbar nach dem schließenden</title>-Tag eingefügt.
- Ein
- Die Inhalte des Verzeichnis
Klicken Sie auf Debuggen>Starten ohne Debugging, um die App in einem Browser zu starten, ohne den Debugger anzufügen. Die Datei
wwwroot/index.htmlwird unterhttp://localhost:<port_number>bereitgestellt.Wenn Sie Kompilierungsfehlermeldungen erhalten, versuchen Sie, die Projektmappe zu schließen und erneut zu öffnen.
Öffnen Sie eine weitere Browserinstanz (beliebiger Browser). Fügen Sie die URL in die Adressleiste ein.
Wählen Sie einen beliebigen Browser aus, geben Sie etwas im Textfeld Nachricht ein, und wählen Sie Senden aus. Der eindeutige Benutzername und die Nachricht werden sofort auf beiden Seiten angezeigt.
Weitere Ressourcen
In diesem Tutorial wird veranschaulicht, wie Webpack in einer ASP.NET Core SignalR-Web-App verwendet wird, um einen in TypeScript geschriebenen Client zu bündeln und zu erstellen. Mit Webpack können Entwickler clientseitige Ressourcen einer Web-App bündeln und erstellen.
In diesem Tutorial lernen Sie Folgendes:
- Aufbauen einer einfachen ASP.NET Core SignalR-App
- Konfigurieren des SignalR-TypeScript-Clients
- Konfigurieren einer Buildpipeline mithilfe von Webpack
- Konfigurieren des SignalR-Servers
- Aktivieren der Kommunikation zwischen Client und Server
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Prerequisites
- Visual Studio 2019 mit der Workload für ASP.NET und Webentwicklung
- .NET Core SDK 2.2 oder höher
- Node.js mit NPM
Erstellen einer ASP.NET Core-Web-App
Konfigurieren Sie Visual Studio, damit in der Umgebungsvariable PATH nach NPM gesucht wird. Visual Studio verwendet standardmäßig die Version von NPM, die sich im Installationsverzeichnis befindet. Führen Sie die folgenden Anweisungen in Visual Studio aus:
Navigieren Sie zu Extras>Optionen>Projekte und Lösungen>Webpaketverwaltung>Externe Webtools.
Wählen Sie in der Liste den Eintrag $(PATH) aus. Drücken Sie die NACH-OBEN-TASTE, um den Eintrag auf die zweite Position in der Liste zu verschieben.
Die Konfiguration von Visual Studio ist abgeschlossen. Jetzt ist es an der Zeit, das Projekt zu erstellen.
- Verwenden Sie die Menüoption Datei>Neu>Projekt, und wählen Sie die Vorlage ASP.NET Core-Web-App aus.
- Nennen Sie das Projekt *SignalRWebPack` und wählen Sie Erstellen aus.
- Wählen Sie in der Zielframework-Dropdownliste .NET Core und in der Framework-Auswahl-Dropdownliste ASP.NET Core 2.2 aus. Wählen Sie die leere Vorlage und dann Erstellen aus.
Konfigurieren von Webpack und TypeScript
In den folgenden Schritten wird die Konvertierung von TypeScript zu JavaScript und die Bündelung clientseitiger Ressourcen konfiguriert.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json-Datei zu erstellen:npm init -yFügen Sie der
package.json-Datei die hervorgehobene Eigenschaft hinzu:{ "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" }Durch Festlegen der Eigenschaft
privateauftruewerden Warnungen bei der Paketinstallation im nächsten Schritt verhindert.Installieren Sie die erforderlichen NPM-Pakete. Führen Sie den folgenden Befehl über den Projektstamm aus:
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.3Beachten Sie die folgenden Befehlsdetails:
- Auf das
@-Zeichen folgt bei jedem Paketnamen eine Versionsnummer. Die spezifischen Paketversionen werden von NPM installiert. - Die Option
-Edeaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionierung in die Datei „*packagejson“ schreibt. Beispielsweise wird"webpack": "4.29.3"anstelle von"webpack": "^4.29.3"verwendet. Diese Option verhindert unbeabsichtigte Upgrades auf neuere Paketversionen.
Ausführliche Informationen finden Sie in der Dokumentation zu npm-install.
- Auf das
Ersetzen Sie die
scripts-Eigenschaft der Dateipackage.jsondurch den folgenden Code:"scripts": { "build": "webpack --mode=development --watch", "release": "webpack --mode=production", "publish": "npm run release && dotnet publish -c Release" },Im Folgenden werden die Skripts erklärt:
-
build: Bündelt die clientseitigen Ressourcen im Entwicklungsmodus und prüft auf Änderungen an Dateien. Der Dateiwatcher generiert das Bündel jedes Mal neu, wenn eine Änderung an einer Projektdatei vorgenommen wird. Die Optionmodedeaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuildnur in der Entwicklung. -
release: Bündelt clientseitige Ressourcen im Produktionsmodus -
publish: Führt dasrelease-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET-CLI auf, um die App zu veröffentlichen.
-
Erstellen Sie eine Datei namens
*webpack.config.jsim Projektstamm mit dem folgenden Code: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" }) ] };Die vorangehende Datei konfiguriert die Webpack-Kompilierung. Zu beachtende Konfigurationsdetails:
- Die Eigenschaft
outputüberschreibt den Standardwert vondist. Das Bundle wird stattdessen an das Verzeichniswwwrootausgegeben. - Das
resolve.extensions-Array schließt.jsein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Erstellen Sie ein neues src-Verzeichnis im Projektstamm, um die clientseitigen Ressourcen des Projekts zu speichern.
Erstellen Sie
src/index.htmlmit dem folgenden Markup.<!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>Der vorangehende HTML-Code definiert die Markupbausteine der Homepage.
Erstellen Sie ein neues src/css-Verzeichnis. Es dient als Speicherort für die
.css-Dateien des Projekts.Erstellen Sie
src/css/main.cssmit dem folgenden Markup:*, *::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; }Die vorangehende Datei
main.cssformatiert die App.Erstellen Sie
src/tsconfig.jsonmit dem folgenden JSON:{ "compilerOptions": { "target": "es5" } }Der vorangehende Code konfiguriert den TypeScript-Compiler, um JavaScript-Code zu erstellen, der mit ECMAScript 5 kompatibel ist.
Erstellen Sie
src/index.tsmit dem folgenden Code: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() { }Der vorangehende TypeScript-Code ruft Verweise auf DOM-Elemente ab und fügt zwei Ereignishandler an:
-
keyup: Dieses Ereignis wird ausgelöst, wenn der Benutzer etwas in dastbMessage-Textfeld eingibt. Die Funktionsendwird aufgerufen, wenn der Benutzer die EINGABETASTE drückt. -
click: Dieses Ereignis wird ausgelöst, wenn der*die Benutzer*in die Schaltfläche Senden auswählt. Die Funktionsendwird aufgerufen.
-
Konfigurieren einer ASP.NET Core-App
Der in der Methode
Startup.Configurebereitgestellte Code zeigt Hallo Welt! an. Ersetzen Sie den Aufruf der Methodeapp.Rundurch Aufrufe von UseDefaultFiles(IApplicationBuilder) und UseStaticFiles(IApplicationBuilder).app.UseDefaultFiles(); app.UseStaticFiles();Mit dem vorangehenden Code wird dem Server ermöglicht, die Datei
index.htmlzu finden und bereitzustellen, unabhängig davon, ob der Benutzer die vollständige URL oder die Stamm-URL der Web-App eingibt.Rufen Sie AddSignalR in
Startup.ConfigureServicesauf. Mit ihr werden die SignalR-Dienste in das Projekt eingefügt.services.AddSignalR();Ordnen Sie eine /hub-Route dem
ChatHub-Hub zu. Fügen Sie die folgenden Zeilen am Ende vonStartup.Configurehinzu:app.UseSignalR(options => { options.MapHub<ChatHub>("/hub"); });Erstellen Sie ein neues Verzeichnis namens Hubs am Projektstamm. Es dient als Speicherort des SignalR-Hubs, der im nächsten Schritt erstellt wird.
Erstellen Sie mit dem folgenden Code den Hub
Hubs/ChatHub.cs:using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRWebPack.Hubs { public class ChatHub : Hub { } }Fügen Sie den folgenden Code am Anfang der Datei
Startup.cshinzu, um denChatHub-Verweis aufzulösen:using SignalRWebPack.Hubs;
Aktivieren der Kommunikation zwischen Client und Server
Derzeit zeigt die App ein einfaches Formular zum Senden von Nachrichten an. Es geschieht nichts, wenn Sie es versuchen. Der Server lauscht einer spezifischen Route, aber er verarbeitet gesendete Nachrichten nicht.
Führen Sie den folgenden Befehl auf der Ebene des Projektstamms aus:
npm install @aspnet/signalrDer vorangehende Befehl installiert den SignalR-TypeScript-Client, mit dem der Client Nachrichten an den Server senden kann.
Fügen Sie der Datei
src/index.tsden folgenden hervorgehobenen Code hinzu: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() { }Der vorangehende Code unterstützt das Empfangen von Nachrichten vom Server. Die Klasse
HubConnectionBuildererstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrlkonfiguriert die Hub-URL.Mit SignalR wird der Austausch von Nachrichten zwischen einem Client und einem Server ermöglicht. Jede Nachricht verfügt über einen spezifischen Namen. Beispielsweise können Nachrichten mit dem Namen
messageReceiveddie Logik zum Anzeigen neuer Nachrichten im Nachrichtenbereich ausführen. Mit deron-Funktion kann eine spezifische Nachricht belauscht werden. Sie können auf eine beliebige Anzahl von Nachrichtennamen lauschen. Außerdem können Parameter an die Nachricht übergeben werden, z.B. der Name des Autors und der Inhalt der empfangenen Nachricht. Sobald der Client eine Nachricht empfängt, wird ein neuesdivElement erstellt, bei dem der Name und der Nachrichteninhalt des Autors als untergeordnete Elemente mithilfe vontextContentangefügt werden. Die neue Nachricht wird dem Hauptelementdivhinzugefügt, das die Nachrichten anzeigt.Da der Client nun dazu in der Lage ist, Nachrichten zu empfangen, konfigurieren Sie ihn zum Senden von Nachrichten. Fügen Sie der Datei
src/index.tsden folgenden hervorgehobenen Code hinzu: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 = ""); }Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
senderforderlich. Der erste Parameter der Methode ist der Name der Nachricht. Die Nachrichtendaten befinden sich in den anderen Parametern. In diesem Beispiel wird eine Nachricht, die alsnewMessageerkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Eingabe des Benutzers aus einem Textfeld. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.Fügen Sie der Klasse
NewMessagedie MethodeChatHubhinzu: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); } } }Der vorangehende Code überträgt die empfangenen Nachrichten an alle verbundenen Benutzer, sobald der Server sie empfängt. Es ist nicht notwendig, eine generische
on-Methode zum Empfangen aller Nachrichten zu verwenden. Eine Methode benannt nach dem Namen der Nachricht genügt.In diesem Beispiel sendet der TypeScript-Client eine Nachricht, die als
newMessageerkannt wurde. Die C#-MethodeNewMessageerwartet die vom Client gesendeten Daten. Es erfolgt ein Aufruf über SendAsync bei Clients.All. Die empfangenen Nachrichten werden an alle mit dem Hub verbundenen Clients gesendet.
Testen der App
Mit den folgenden Schritten können Sie überprüfen, ob die App funktioniert.
Führen Sie Webpack im Releasemodus aus. Führen Sie im Fenster der Paket-Manager-Konsole den folgenden Befehl im Projekt-Root aus. Wenn Sie sich nicht im Projektstammverzeichnis befinden, geben Sie
cd SignalRWebPackein, bevor Sie den Befehl eingeben.npm run releaseDieser Befehl generiert die clientseitigen Ressourcen, die zur Verfügung gestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwrootgespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwrootwurden bereinigt. - TypeScript wurde in JavaScript konvertiert. Dieser Prozess ist als Transpilierung bekannt.
- Der generierte JavaScript-Code wurde gekürzt, um die Dateigröße zu reduzieren. Dieser Prozess ist als Minimierung bekannt.
- Die verarbeiteten JavaScript-, CSS- und HTML-Dateien wurden aus
srcin das Verzeichniswwwrootkopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.htmleingefügt:- Ein
<link>-Tag, das auf diewwwroot/main.<hash>.css-Datei verweist Dieses Tag wird unmittelbar vor dem schließenden Tag</head>platziert. - Ein
<script>-Tag, das auf die verkleinertewwwroot/main.<hash>.js-Datei verweist Dieses Tag wird unmittelbar nach dem schließenden</title>-Tag eingefügt.
- Ein
- Die Inhalte des Verzeichnis
Klicken Sie auf Debuggen>Starten ohne Debugging, um die App in einem Browser zu starten, ohne den Debugger anzufügen. Die Datei
wwwroot/index.htmlwird unterhttp://localhost:<port_number>bereitgestellt.Öffnen Sie eine weitere Browserinstanz (beliebiger Browser). Fügen Sie die URL in die Adressleiste ein.
Wählen Sie einen beliebigen Browser aus, geben Sie etwas im Textfeld Nachricht ein, und wählen Sie Senden aus. Der eindeutige Benutzername und die Nachricht werden sofort auf beiden Seiten angezeigt.