Tutorial: Erste Schritte mit ASP.NET Core SignalR mit TypeScript und Webpack
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Informationen zum aktuellen Release finden Sie in der .NET 8-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
- Herstellen der Kommunikation zwischen dem Client und dem Server
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Voraussetzungen
Visual Studio 2022 mit der Workload 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 Projektmappen>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 Weiter aus.
- 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.cs
auf:var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();
Rufen Sie in
Program.cs
nun 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
Hubs
ein neues Verzeichnis namensSignalRWebpack/
für die SignalR-Hubklasse.Erstellen Sie die neue Datei
Hubs/ChatHub.cs
mit 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
newMessage
erkannt wurde. - Die C#-Methode
NewMessage
erwartet die vom Client gesendeten Daten. - Es erfolgt ein Aufruf an SendAsync für 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.cs
ein, um denChatHub
-Verweis aufzulösen:using SignalRWebpack.Hubs;
Ordnen Sie in
Program.cs
die Route/hub
dem HubChatHub
zu. Ersetzen Sie den Code fürHello World!
durch den folgenden Code:app.MapHub<ChatHub>("/hub");
Konfigurieren des Clients
In diesem Abschnitt erstellen Sie ein Node.js-Projekt , um TypeScript in JavaScript zu konvertieren und clientseitige Ressourcen, einschließlich HTML und CSS, mithilfe von Webpack zu bündeln.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json
-Datei zu erstellen:npm init -y
Fü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
private
auftrue
werden 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-cli
Die Option
-E
deaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionsverwaltung in die Dateipackage.json
schreibt. 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.json
durch 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 Optionmode
deaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuild
nur bei der Entwicklung.release
: Bündelt clientseitige Ressourcen im Produktionsmoduspublish
: 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.js
im 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 Bündel wird stattdessen an das Verzeichniswwwroot
ausgegeben. - Das
resolve.extensions
-Array schließt.js
ein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Erstellen Sie ein neues Verzeichnis namens
src
im Projektstamm (SignalRWebpack/
) für den Clientcode.Kopieren Sie das Verzeichnis
src
und dessen Inhalt aus dem Beispielprojekt in den Projektstamm. Das Verzeichnissrc
enthä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 TextfeldtbMessage
macht. Die Funktionsend
wird 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 Funktionsend
aufgerufen wird.
Die Klasse
HubConnectionBuilder
erstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrl
konfiguriert 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
messageReceived
die 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 neuesdiv
-Element mit dem Namen des Autors und dem Inhalt der Nachricht iminnerHTML
-Attribut erstellt. Es wird dem Hauptelementdiv
hinzugefügt, das die Nachrichten anzeigt.Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
send
erforderlich. 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 alsnewMessage
erkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Benutzereingabe eines Textfelds. 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/node
Mit dem vorangestellten Komma wird Folgendes installiert:
- 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
aus. Führen Sie im Fenster Paket-Manager-Konsole den folgenden Befehl im Projektstammverzeichnis aus.npm run release
Dieser Befehl generiert die clientseitigen Objekte an, die bereitgestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwroot
gespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwroot
wurden 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
src
in das Verzeichniswwwroot
kopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.html
eingefü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.html
wird 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
Zusätzliche 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
- Herstellen der Kommunikation zwischen dem Client und dem Server
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Voraussetzungen
Visual Studio 2022 mit der Workload 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 Projektmappen>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 Weiter aus.
- Geben Sie dem Projekt den Namen
SignalRWebpack
, und wählen Sie Erstellen aus. - Wählen Sie
.NET 7.0 (Standard Term Support)
aus dem Dropdownmenü Framework aus. Klicken Sie auf Erstellen.
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.cs
auf:var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();
Rufen Sie in
Program.cs
nun 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
Hubs
ein neues Verzeichnis namensSignalRWebpack/
für die SignalR-Hubklasse.Erstellen Sie die neue Datei
Hubs/ChatHub.cs
mit 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
newMessage
erkannt wurde. - Die C#-Methode
NewMessage
erwartet die vom Client gesendeten Daten. - Es erfolgt ein Aufruf an SendAsync für 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.cs
ein, um denChatHub
-Verweis aufzulösen:using SignalRWebpack.Hubs;
Ordnen Sie in
Program.cs
die Route/hub
dem HubChatHub
zu. Ersetzen Sie den Code fürHello World!
durch den folgenden Code:app.MapHub<ChatHub>("/hub");
Konfigurieren des Clients
In diesem Abschnitt erstellen Sie ein Node.js-Projekt , um TypeScript in JavaScript zu konvertieren und clientseitige Ressourcen, einschließlich HTML und CSS, mithilfe von Webpack zu bündeln.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json
-Datei zu erstellen:npm init -y
Fü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
private
auftrue
werden 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-cli
Die Option
-E
deaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionsverwaltung in die Dateipackage.json
schreibt. 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.json
durch 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 Optionmode
deaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuild
nur bei der Entwicklung.release
: Bündelt clientseitige Ressourcen im Produktionsmoduspublish
: 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.js
im 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 Bündel wird stattdessen an das Verzeichniswwwroot
ausgegeben. - Das
resolve.extensions
-Array schließt.js
ein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Kopieren Sie das Verzeichnis
src
und dessen Inhalt aus dem Beispielprojekt in den Projektstamm. Das Verzeichnissrc
enthä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 TextfeldtbMessage
macht. Die Funktionsend
wird 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 Funktionsend
aufgerufen wird.
Die Klasse
HubConnectionBuilder
erstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrl
konfiguriert 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
messageReceived
die 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 neuesdiv
-Element mit dem Namen des Autors und dem Inhalt der Nachricht iminnerHTML
-Attribut erstellt. Es wird dem Hauptelementdiv
hinzugefügt, das die Nachrichten anzeigt.Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
send
erforderlich. 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 alsnewMessage
erkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Benutzereingabe eines Textfelds. 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/node
Mit dem vorangestellten Komma wird Folgendes installiert:
- 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
aus. Führen Sie im Fenster Paket-Manager-Konsole den folgenden Befehl im Projektstammverzeichnis aus.npm run release
Dieser Befehl generiert die clientseitigen Objekte an, die bereitgestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwroot
gespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwroot
wurden 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
src
in das Verzeichniswwwroot
kopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.html
eingefü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.html
wird 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
Zusätzliche 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
- Herstellen der Kommunikation zwischen dem Client und dem Server
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Voraussetzungen
- Visual Studio 2022 mit der Workload ASP.NET und Webentwicklung
- .NET 6.0 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 Projektmappen>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 Weiter aus.
- Geben Sie dem Projekt den Namen
SignalRWebpack
, und wählen Sie Erstellen aus. - Wählen Sie
.NET 6.0 (Long Term Support)
aus dem Dropdownmenü Framework aus. Klicken Sie auf Erstellen.
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.cs
auf:var builder = WebApplication.CreateBuilder(args); builder.Services.AddSignalR();
Rufen Sie in
Program.cs
nun 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
Hubs
ein neues Verzeichnis namensSignalRWebpack/
für die SignalR-Hubklasse.Erstellen Sie die neue Datei
Hubs/ChatHub.cs
mit 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
newMessage
erkannt wurde. Die C#-MethodeNewMessage
erwartet die vom Client gesendeten Daten. Es erfolgt ein Aufruf an SendAsync für Clients.All. Die empfangenen Nachrichten werden an alle mit dem Hub verbundenen Clients gesendet.Fügen Sie die folgende
using
-Anweisung am Anfang vonProgram.cs
ein, um denChatHub
-Verweis aufzulösen:using SignalRWebpack.Hubs;
Ordnen Sie in
Program.cs
die Route/hub
dem HubChatHub
zu. Ersetzen Sie den Code fürHello World!
durch den folgenden Code:app.MapHub<ChatHub>("/hub");
Konfigurieren des Clients
In diesem Abschnitt erstellen Sie ein Node.js-Projekt , um TypeScript in JavaScript zu konvertieren und clientseitige Ressourcen, einschließlich HTML und CSS, mithilfe von Webpack zu bündeln.
Führen Sie den folgenden Befehl im Projektstamm aus, um eine
package.json
-Datei zu erstellen:npm init -y
Fü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
private
auftrue
werden 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-cli
Die Option
-E
deaktiviert das Standardverhalten von npm, das Bereichsoperatoren für die semantische Versionsverwaltung in die Dateipackage.json
schreibt. 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.json
durch 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 Optionmode
deaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuild
nur bei der Entwicklung.release
: Bündelt clientseitige Ressourcen im Produktionsmoduspublish
: 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.js
im 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 Bündel wird stattdessen an das Verzeichniswwwroot
ausgegeben. - Das
resolve.extensions
-Array schließt.js
ein, um den JavaScript-Code des SignalR-Clients zu importieren.
- Die Eigenschaft
Kopieren Sie das Verzeichnis
src
und dessen Inhalt aus dem Beispielprojekt in den Projektstamm. Das Verzeichnissrc
enthä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 TextfeldtbMessage
macht. Die Funktionsend
wird 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 Funktionsend
aufgerufen wird.
Die Klasse
HubConnectionBuilder
erstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrl
konfiguriert 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
messageReceived
die 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 neuesdiv
-Element mit dem Namen des Autors und dem Inhalt der Nachricht iminnerHTML
-Attribut erstellt. Es wird dem Hauptelementdiv
hinzugefügt, das die Nachrichten anzeigt.Für das Senden einer Nachricht über die WebSockets-Verbindung ist das Aufrufen der Methode
send
erforderlich. 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 alsnewMessage
erkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Benutzereingabe eines Textfelds. 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/node
Mit dem vorangestellten Komma wird Folgendes installiert:
- 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
aus. Führen Sie im Fenster Paket-Manager-Konsole den folgenden Befehl im Projektstammverzeichnis aus. Wenn Sie sich nicht im Projektstammverzeichnis befinden, geben Siecd SignalRWebpack
ein, bevor Sie den Befehl eingeben.npm run release
Dieser Befehl generiert die clientseitigen Objekte an, die bereitgestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwroot
gespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwroot
wurden 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
src
in das Verzeichniswwwroot
kopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.html
eingefü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.html
wird 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
Zusätzliche 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, wie die folgenden Aufgaben ausgeführt werden:
- 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)
Voraussetzungen
- Visual Studio 2019 mit der Workload 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 Projektmappen>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 Weiter aus.
- Benennen 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 -y
Fü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
private
auftrue
werden 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.10
Beachten Sie folgende Informationen:
- Auf das
@
-Zeichen folgt bei jedem Paketnamen eine Versionsnummer. Die spezifischen Paketversionen werden von NPM installiert. - Die Option
-E
deaktiviert 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.json
durch 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 Optionmode
deaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuild
nur in der Entwicklung.release
: Bündelt clientseitige Ressourcen im Produktionsmoduspublish
: Führt dasrelease
-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET Core-CLI auf, um die App zu veröffentlichen.
Erstellen Sie eine Datei namens
webpack.config.js
im 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 Bündel wird stattdessen an das Verzeichniswwwroot
ausgegeben. - Das
resolve.extensions
-Array schließt.js
ein, 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.html
mit 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.css
mit 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.css
formatiert die App.Erstellen Sie
src/tsconfig.json
mit 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.ts
mit 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 Funktionsend
wird 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 Funktionsend
wird aufgerufen.
Konfigurieren der App
Fügen Sie in
Startup.Configure
Aufrufe von 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.Configure
eine /hub-Route demChatHub
-Hub zu. Ersetzen Sie den Code, der Hello World! anzeigt, durch die folgende Zeile:app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/hub"); });
Rufen Sie AddSignalR in
Startup.ConfigureServices
auf.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.cs
ein, 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/node
Mit dem vorangestellten Komma wird Folgendes installiert:
- 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.ts
den 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"); 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() { }
Der vorangehende Code unterstützt das Empfangen von Nachrichten vom Server. Die Klasse
HubConnectionBuilder
erstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrl
konfiguriert 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
messageReceived
die 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 neuesdiv
-Element mit dem Namen des Autors und dem Inhalt der Nachricht iminnerHTML
-Attribut erstellt. Es wird dem Hauptelementdiv
hinzugefü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.ts
den 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"); messages.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`; 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
send
erforderlich. 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 alsnewMessage
erkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Benutzereingabe eines Textfelds. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.Fügen Sie der Klasse
ChatHub
die MethodeNewMessage
hinzu: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 mit demselben Namen wie die Nachricht genügt.In diesem Beispiel sendet der TypeScript-Client eine Nachricht, die als
newMessage
erkannt wurde. Die C#-MethodeNewMessage
erwartet die vom Client gesendeten Daten. Es erfolgt ein Aufruf an SendAsync für 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 Paket-Manager-Konsole den folgenden Befehl im Projektstammverzeichnis aus. Wenn Sie sich nicht im Projektstammverzeichnis befinden, geben Sie
cd SignalRWebPack
ein, bevor Sie den Befehl eingeben.npm run release
Dieser Befehl generiert die clientseitigen Objekte an, die bereitgestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwroot
gespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwroot
wurden 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
src
in das Verzeichniswwwroot
kopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.html
eingefü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.html
wird 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.
Zusätzliche 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, wie die folgenden Aufgaben ausgeführt werden:
- 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)
Voraussetzungen
- Visual Studio 2019 mit der Workload 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 Projektmappen>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.
- Benennen Sie das Projekt *SignalRWebPack`, 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 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 -y
Fü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
private
auftrue
werden 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.3
Beachten Sie folgende Informationen:
- Auf das
@
-Zeichen folgt bei jedem Paketnamen eine Versionsnummer. Die spezifischen Paketversionen werden von NPM installiert. - Die Option
-E
deaktiviert 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.json
durch 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 Optionmode
deaktiviert Produktionsoptimierungsvorgänge wie das „Tree Shaking“ und die „Minimierung“. Verwenden Siebuild
nur in der Entwicklung.release
: Bündelt clientseitige Ressourcen im Produktionsmoduspublish
: Führt dasrelease
-Skript aus, um die clientseitigen Ressourcen im Produktionsmodus zu bündeln. Es ruft den publish-Befehl der .NET Core-CLI auf, um die App zu veröffentlichen.
Erstellen Sie eine Datei namens
*webpack.config.js
im 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 Bündel wird stattdessen an das Verzeichniswwwroot
ausgegeben. - Das
resolve.extensions
-Array schließt.js
ein, 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.html
mit 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.css
mit 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.css
formatiert die App.Erstellen Sie
src/tsconfig.json
mit 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.ts
mit 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 Funktionsend
wird 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 Funktionsend
wird aufgerufen.
Konfigurieren einer ASP.NET Core-App
Der in der Methode
Startup.Configure
bereitgestellte Code zeigt Hello World! an. Ersetzen Sie den Aufruf der Methodeapp.Run
durch Aufrufe von UseDefaultFiles(IApplicationBuilder) und UseStaticFiles(IApplicationBuilder).app.UseDefaultFiles(); app.UseStaticFiles();
Mit dem vorangehenden Code wird dem Server ermöglicht, die Datei
index.html
zu finden und bereitzustellen, unabhängig davon, ob der Benutzer die vollständige URL oder die Stamm-URL der Web-App eingibt.Rufen Sie
Startup.ConfigureServices
in AddSignalR auf. Mit ihr werden die SignalR-Dienste in das Projekt eingefügt.services.AddSignalR();
Ordnen Sie dem
ChatHub
-Hub eine /hub-Route zu. Fügen Sie die folgenden Zeilen am Ende vonStartup.Configure
hinzu: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.cs
hinzu, 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 jedoch nichts, wenn Sie versuchen, es zu verwenden. 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/signalr
Der vorangehende Befehl installiert den SignalR-TypeScript-Client, mit dem der Client Nachrichten an den Server senden kann.
Fügen Sie der Datei
src/index.ts
den 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"); 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.keyCode === 13) { send(); } }); btnSend.addEventListener("click", send); function send() { }
Der vorangehende Code unterstützt das Empfangen von Nachrichten vom Server. Die Klasse
HubConnectionBuilder
erstellt einen neuen Generator für die Konfiguration der Serververbindung. Die FunktionwithUrl
konfiguriert 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
messageReceived
die 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 neuesdiv
-Element mit dem Namen des Autors und dem Inhalt der Nachricht iminnerHTML
-Attribut erstellt. Die neue Nachricht wird dem Hauptelementdiv
hinzugefü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.ts
den 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"); messageContainer.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`; 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
send
erforderlich. 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 alsnewMessage
erkannt wird, an den Server gesendet. Die Nachricht besteht aus dem Benutzernamen und der Benutzereingabe eines Textfelds. Wenn das Senden funktioniert hat, wird der Textfeldwert gelöscht.Fügen Sie der Klasse
ChatHub
die MethodeNewMessage
hinzu: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 mit demselben Namen wie die Nachricht genügt.In diesem Beispiel sendet der TypeScript-Client eine Nachricht, die als
newMessage
erkannt wurde. Die C#-MethodeNewMessage
erwartet die vom Client gesendeten Daten. Es erfolgt ein Aufruf an SendAsync für 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 Paket-Manager-Konsole den folgenden Befehl im Projektstammverzeichnis aus. Wenn Sie sich nicht im Projektstammverzeichnis befinden, geben Sie
cd SignalRWebPack
ein, bevor Sie den Befehl eingeben.npm run release
Dieser Befehl generiert die clientseitigen Objekte an, die bereitgestellt werden, wenn die App ausgeführt wird. Die Objekte werden im Ordner
wwwroot
gespeichert.Webpack hat die folgenden Aufgaben durchgeführt:
- Die Inhalte des Verzeichnis
wwwroot
wurden 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
src
in das Verzeichniswwwroot
kopiert. - Die folgenden Elemente wurden in die Datei
wwwroot/index.html
eingefü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.html
wird 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.
Zusätzliche Ressourcen
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für