Samouczek: rozpoczynanie pracy z platformą ASP.NET Core SignalR przy użyciu języka TypeScript i pakietu WebPack

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Autor: Sébastien Sougnez

W tym samouczku pokazano używanie pakietu Webpack w aplikacji internetowej ASP.NET Core SignalR w celu tworzenia pakietu i kompilowania klienta napisanego w języku TypeScript. Pakiet Webpack umożliwia deweloperom łączenie i tworzenie zasobów po stronie klienta aplikacji internetowej.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Tworzenie aplikacji ASP.NET Core SignalR
  • SignalR Konfigurowanie serwera
  • Konfigurowanie potoku kompilacji przy użyciu pakietu WebPack
  • SignalR Konfigurowanie klienta Języka TypeScript
  • Włączanie komunikacji między klientem a serwerem

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

  • Node.js za pomocą narzędzia npm

Tworzenie aplikacji internetowej platformy ASP.NET Core

Domyślnie program Visual Studio używa wersji narzędzia npm znalezionej w katalogu instalacyjnym. Aby skonfigurować program Visual Studio pod kątem wyszukiwania narzędzia npm w zmiennej środowiskowej PATH :

Uruchom program Visual Studio. W oknie startowym wybierz pozycję Kontynuuj bez kodu.

  1. Przejdź do pozycji Narzędzia>Opcje>Projekty i rozwiązania>Web Package Management>Zewnętrzne narzędzia sieci Web.

  2. $(PATH) Wybierz wpis z listy. Wybierz strzałkę w górę, aby przenieść wpis na drugą pozycję na liście, a następnie wybierz przycisk OK:

    Konfiguracja programu Visual Studio.

Aby utworzyć nową aplikację internetową ASP.NET Core:

  1. Użyj opcji menu Plik>nowy>projekt i wybierz szablon ASP.NET Core Empty. Wybierz Dalej.
  2. Nadaj projektowi SignalRWebpacknazwę , a następnie wybierz pozycję Utwórz.
  3. Z listy rozwijanej Framework wybierz pozycję .NET 8.0 (obsługa długoterminowa). Wybierz pozycję Utwórz.

Dodaj pakiet NuGet Microsoft.TypeScript.MSBuild do projektu:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł projektu i wybierz polecenie Zarządzaj pakietami NuGet. Na karcie Przeglądaj wyszukajMicrosoft.TypeScript.MSBuild, a następnie wybierz pozycję Zainstaluj po prawej stronie, aby zainstalować pakiet.

Program Visual Studio dodaje pakiet NuGet w węźle Zależności w Eksplorator rozwiązań, włączając kompilację języka TypeScript w projekcie.

Konfigurowanie serwera

W tej sekcji skonfigurujesz aplikację internetową platformy ASP.NET Core do wysyłania i odbierania SignalR komunikatów.

  1. W Program.cspliku wywołaj metodę AddSignalR:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddSignalR();
    
  2. Ponownie w pliku Program.cswywołaj metodę UseDefaultFiles i UseStaticFiles:

    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseStaticFiles();
    

    Powyższy kod umożliwia serwerowi lokalizowanie i obsługę index.html pliku. Plik jest obsługiwany, czy użytkownik wprowadza pełny adres URL, czy główny adres URL aplikacji internetowej.

  3. Utwórz nowy katalog o nazwie Hubs w katalogu głównym SignalRWebpack/projektu , dla SignalR klasy centrum.

  4. Utwórz nowy plik z Hubs/ChatHub.csnastępującym kodem:

    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);
    }
    

    Powyższy kod rozgłasza odebrane komunikaty do wszystkich połączonych użytkowników po odebraniu ich przez serwer. Nie trzeba mieć ogólnej on metody odbierania wszystkich komunikatów. Wystarczy metoda o nazwie o nazwie komunikatu.

    W tym przykładzie:

    • Klient TypeScript wysyła komunikat zidentyfikowany jako newMessage.
    • Metoda języka C# NewMessage oczekuje danych wysyłanych przez klienta.
    • Wywołanie jest wykonywane na SendAsync stronie Clients.All.
    • Odebrane komunikaty są wysyłane do wszystkich klientów połączonych z koncentratorem.
  5. Dodaj następującą using instrukcję w górnej części, Program.cs aby rozwiązać ChatHub ten problem:

    using SignalRWebpack.Hubs;
    
  6. W Program.cspliku zamapuj /hubChatHub trasę na koncentrator. Zastąp kod wyświetlany Hello World! następującym kodem:

    app.MapHub<ChatHub>("/hub");
    

Konfigurowanie klienta

W tej sekcji utworzysz projekt Node.js , aby przekonwertować język TypeScript na język JavaScript i powiązać zasoby po stronie klienta, w tym html i CSS, przy użyciu pakietu WebPack.

  1. Uruchom następujące polecenie w katalogu głównym projektu, aby utworzyć package.json plik:

    npm init -y
    
  2. Dodaj wyróżnioną właściwość do package.json pliku i zapisz zmiany w pliku:

    {
      "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"
    }
    

    private Ustawienie właściwości w celu true uniemożliwinia instalowania pakietów ostrzeżeń w następnym kroku.

  3. Zainstaluj wymagane pakiety npm. Uruchom następujące polecenie z poziomu głównego projektu:

    npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cli
    

    Opcja -E wyłącza domyślne zachowanie narzędzia npm podczas pisania operatorów zakresu obsługi wersji semantycznych na package.json. Na przykład "webpack": "5.76.1" jest używany zamiast "webpack": "^5.76.1". Ta opcja uniemożliwia niezamierzone uaktualnienia do nowszych wersji pakietów.

    Aby uzyskać więcej informacji, zobacz dokumentację npm-install .

  4. Zastąp scripts właściwość package.json pliku następującym kodem:

    "scripts": {
      "build": "webpack --mode=development --watch",
      "release": "webpack --mode=production",
      "publish": "npm run release && dotnet publish -c Release"
    },
    

    Zdefiniowane są następujące skrypty:

    • build: łączy zasoby po stronie klienta w trybie programowania i obserwuje zmiany plików. Obserwator plików powoduje ponowne wygenerowanie pakietu za każdym razem, gdy zmienia się plik projektu. Opcja mode wyłącza optymalizacje produkcyjne, takie jak drżenie drzewa i minimalizowanie. używać build tylko w środowisku programistycznym.
    • release: łączy zasoby po stronie klienta w trybie produkcyjnym.
    • publish: uruchamia release skrypt, aby powiązać zasoby po stronie klienta w trybie produkcyjnym. Wywołuje polecenie publikowania interfejsu wiersza polecenia platformy .NET w celu opublikowania aplikacji.
  5. Utwórz plik o nazwie webpack.config.js w katalogu głównym projektu z następującym kodem:

    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",
            }),
        ],
    };
    

    Powyższy plik konfiguruje proces kompilacji pakietu WebPack:

    • Właściwość output zastępuje wartość domyślną .dist Pakiet jest zamiast tego emitowany w wwwroot katalogu.
    • Tablica resolve.extensions obejmuje .js importowanie SignalR kodu JavaScript klienta.
  6. Utwórz nowy katalog o nazwie src w katalogu głównym SignalRWebpack/projektu , dla kodu klienta.

  7. src Skopiuj katalog i jego zawartość z przykładowego projektu do katalogu głównego projektu. Katalog src zawiera następujące pliki:

    • index.html, który definiuje standardowy znacznik strony głównej:

      <!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, który udostępnia style CSS dla strony głównej:

      *,
      *::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, który konfiguruje kompilator TypeScript w celu utworzenia kodu JAVAScript zgodnego z językiem ECMAScript 5:

      {
        "compilerOptions": {
          "target": "es5"
        }
      }
      
    • index.ts:

      import * as signalR from "@microsoft/signalr";
      import "./css/main.css";
      
      const divMessages: HTMLDivElement = document.querySelector("#divMessages");
      const tbMessage: HTMLInputElement = document.querySelector("#tbMessage");
      const btnSend: HTMLButtonElement = document.querySelector("#btnSend");
      const username = new Date().getTime();
      
      const connection = new signalR.HubConnectionBuilder()
          .withUrl("/hub")
          .build();
      
      connection.on("messageReceived", (username: string, message: string) => {
        const m = document.createElement("div");
      
        m.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`;
      
        divMessages.appendChild(m);
        divMessages.scrollTop = divMessages.scrollHeight;
      });
      
      connection.start().catch((err) => document.write(err));
      
      tbMessage.addEventListener("keyup", (e: KeyboardEvent) => {
        if (e.key === "Enter") {
          send();
        }
      });
      
      btnSend.addEventListener("click", send);
      
      function send() {
        connection.send("newMessage", username, tbMessage.value)
          .then(() => (tbMessage.value = ""));
      }
      

      Powyższy kod pobiera odwołania do elementów DOM i dołącza dwa programy obsługi zdarzeń:

      • keyup: jest uruchamiany, gdy użytkownik wpisze w tbMessage polu tekstowym i wywołuje send funkcję, gdy użytkownik naciska klawisz Enter .
      • click: jest wyzwalany, gdy użytkownik wybierze przycisk Wyślij i wywoła send funkcję .

      Klasa HubConnectionBuilder tworzy nowego konstruktora do konfigurowania połączenia serwera. Funkcja withUrl konfiguruje adres URL centrum.

      SignalR umożliwia wymianę komunikatów między klientem a serwerem. Każda wiadomość ma określoną nazwę. Na przykład komunikaty o nazwie messageReceived mogą uruchamiać logikę odpowiedzialną za wyświetlanie nowego komunikatu w strefie komunikatów. Nasłuchiwanie określonego komunikatu on można wykonać za pośrednictwem funkcji . Można nasłuchiwać dowolnej liczby nazw wiadomości. Istnieje również możliwość przekazania parametrów do wiadomości, takich jak nazwa autora i zawartość odebranego komunikatu. Gdy klient otrzyma komunikat, zostanie utworzony nowy div element z nazwą autora i zawartością komunikatu w jego innerHTML atrybucie. Jest dodawany do głównego div elementu wyświetlającego komunikaty.

      Wysłanie komunikatu za pośrednictwem połączenia WebSockets wymaga wywołania send metody . Pierwszy parametr metody to nazwa komunikatu. Dane komunikatu zamieszkają inne parametry. W tym przykładzie komunikat zidentyfikowany jako newMessage jest wysyłany do serwera. Komunikat składa się z nazwy użytkownika i danych wejściowych użytkownika z pola tekstowego. Jeśli wysyłanie działa, wartość pola tekstowego zostanie wyczyszczone.

  8. Uruchom następujące polecenie w katalogu głównym projektu:

    npm i @microsoft/signalr @types/node
    

    Poprzednie polecenie instaluje:

    • SignalR Klient TypeScript, który umożliwia klientowi wysyłanie komunikatów do serwera.
    • Definicje typów języka TypeScript dla Node.js, które umożliwiają sprawdzanie czasu kompilacji typów Node.js.

Testowanie aplikacji

Upewnij się, że aplikacja działa z następującymi krokami:

  1. Uruchom pakiet webpack w release trybie. Za pomocą okna konsoli Menedżer pakietów uruchom następujące polecenie w katalogu głównym projektu.

    npm run release
    

    To polecenie generuje zasoby po stronie klienta, które mają być obsługiwane podczas uruchamiania aplikacji. Zasoby są umieszczane w folderze wwwroot .

    Pakiet Webpack wykonał następujące zadania:

    • Przeczyścił zawartość wwwroot katalogu.
    • Przekonwertowano język TypeScript na język JavaScript w procesie znanym jako transpilacja.
    • Wygenerowany kod JavaScript został wygenerowany w celu zmniejszenia rozmiaru pliku w procesie znanym jako minification.
    • Skopiowano przetworzone pliki JavaScript, CSS i HTML z src katalogu wwwroot .
    • W pliku wstrzyknął następujące elementy wwwroot/index.html :
      • <link> Tag, odwołując wwwroot/main.<hash>.css się do pliku. Ten tag jest umieszczany bezpośrednio przed tagiem zamykającym </head> .
      • <script> Tag, odwołując się do pliku minyfikowanegowwwroot/main.<hash>.js. Ten tag jest umieszczany natychmiast po tagu zamykającym </title> .
  2. Wybierz pozycję Debuguj>Rozpocznij bez debugowania, aby uruchomić aplikację w przeglądarce bez dołączania debugera. Plik wwwroot/index.html jest obsługiwany pod adresem https://localhost:<port>.

    Jeśli występują błędy kompilacji, spróbuj zamknąć i ponownie otworzyć rozwiązanie.

  3. Otwórz inne wystąpienie przeglądarki (dowolną przeglądarkę) i wklej adres URL na pasku adresu.

  4. Wybierz jedną z przeglądarek, wpisz coś w polu tekstowym Wiadomość , a następnie wybierz przycisk Wyślij . Unikatowa nazwa użytkownika i komunikat są wyświetlane na obu stronach natychmiast.

Komunikat wyświetlany w obu oknach przeglądarki

Następne kroki

Dodatkowe zasoby

W tym samouczku pokazano używanie pakietu Webpack w aplikacji internetowej ASP.NET Core SignalR w celu tworzenia pakietu i kompilowania klienta napisanego w języku TypeScript. Pakiet Webpack umożliwia deweloperom łączenie i tworzenie zasobów po stronie klienta aplikacji internetowej.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Tworzenie aplikacji ASP.NET Core SignalR
  • SignalR Konfigurowanie serwera
  • Konfigurowanie potoku kompilacji przy użyciu pakietu WebPack
  • SignalR Konfigurowanie klienta Języka TypeScript
  • Włączanie komunikacji między klientem a serwerem

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

  • Node.js za pomocą narzędzia npm

Tworzenie aplikacji internetowej platformy ASP.NET Core

Domyślnie program Visual Studio używa wersji narzędzia npm znalezionej w katalogu instalacyjnym. Aby skonfigurować program Visual Studio pod kątem wyszukiwania narzędzia npm w zmiennej środowiskowej PATH :

Uruchom program Visual Studio. W oknie startowym wybierz pozycję Kontynuuj bez kodu.

  1. Przejdź do pozycji Narzędzia>Opcje>Projekty i rozwiązania>Web Package Management>Zewnętrzne narzędzia sieci Web.

  2. $(PATH) Wybierz wpis z listy. Wybierz strzałkę w górę, aby przenieść wpis na drugą pozycję na liście, a następnie wybierz przycisk OK:

    Konfiguracja programu Visual Studio.

Aby utworzyć nową aplikację internetową ASP.NET Core:

  1. Użyj opcji menu Plik>nowy>projekt i wybierz szablon ASP.NET Core Empty. Wybierz Dalej.
  2. Nadaj projektowi SignalRWebpacknazwę , a następnie wybierz pozycję Utwórz.
  3. Wybierz .NET 7.0 (Standard Term Support) z listy rozwijanej Struktura . Wybierz pozycję Utwórz.

Dodaj pakiet NuGet Microsoft.TypeScript.MSBuild do projektu:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł projektu i wybierz polecenie Zarządzaj pakietami NuGet. Na karcie Przeglądaj wyszukajMicrosoft.TypeScript.MSBuild, a następnie wybierz pozycję Zainstaluj po prawej stronie, aby zainstalować pakiet.

Program Visual Studio dodaje pakiet NuGet w węźle Zależności w Eksplorator rozwiązań, włączając kompilację języka TypeScript w projekcie.

Konfigurowanie serwera

W tej sekcji skonfigurujesz aplikację internetową platformy ASP.NET Core do wysyłania i odbierania SignalR komunikatów.

  1. W Program.cspliku wywołaj metodę AddSignalR:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddSignalR();
    
  2. Ponownie w pliku Program.cswywołaj metodę UseDefaultFiles i UseStaticFiles:

    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseStaticFiles();
    

    Powyższy kod umożliwia serwerowi lokalizowanie i obsługę index.html pliku. Plik jest obsługiwany, czy użytkownik wprowadza pełny adres URL, czy główny adres URL aplikacji internetowej.

  3. Utwórz nowy katalog o nazwie Hubs w katalogu głównym SignalRWebpack/projektu , dla SignalR klasy centrum.

  4. Utwórz nowy plik z Hubs/ChatHub.csnastępującym kodem:

    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);
    }
    

    Powyższy kod rozgłasza odebrane komunikaty do wszystkich połączonych użytkowników po odebraniu ich przez serwer. Nie trzeba mieć ogólnej on metody odbierania wszystkich komunikatów. Wystarczy metoda o nazwie o nazwie komunikatu.

    W tym przykładzie:

    • Klient TypeScript wysyła komunikat zidentyfikowany jako newMessage.
    • Metoda języka C# NewMessage oczekuje danych wysyłanych przez klienta.
    • Wywołanie jest wykonywane na SendAsync stronie Clients.All.
    • Odebrane komunikaty są wysyłane do wszystkich klientów połączonych z koncentratorem.
  5. Dodaj następującą using instrukcję w górnej części, Program.cs aby rozwiązać ChatHub ten problem:

    using SignalRWebpack.Hubs;
    
  6. W Program.cspliku zamapuj /hubChatHub trasę na koncentrator. Zastąp kod wyświetlany Hello World! następującym kodem:

    app.MapHub<ChatHub>("/hub");
    

Konfigurowanie klienta

W tej sekcji utworzysz projekt Node.js , aby przekonwertować język TypeScript na język JavaScript i powiązać zasoby po stronie klienta, w tym html i CSS, przy użyciu pakietu WebPack.

  1. Uruchom następujące polecenie w katalogu głównym projektu, aby utworzyć package.json plik:

    npm init -y
    
  2. Dodaj wyróżnioną właściwość do package.json pliku i zapisz zmiany w pliku:

    {
      "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"
    }
    

    private Ustawienie właściwości w celu true uniemożliwinia instalowania pakietów ostrzeżeń w następnym kroku.

  3. Zainstaluj wymagane pakiety npm. Uruchom następujące polecenie z poziomu głównego projektu:

    npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cli
    

    Opcja -E wyłącza domyślne zachowanie narzędzia npm podczas pisania operatorów zakresu obsługi wersji semantycznych na package.json. Na przykład "webpack": "5.76.1" jest używany zamiast "webpack": "^5.76.1". Ta opcja uniemożliwia niezamierzone uaktualnienia do nowszych wersji pakietów.

    Aby uzyskać więcej informacji, zobacz dokumentację npm-install .

  4. Zastąp scripts właściwość package.json pliku następującym kodem:

    "scripts": {
      "build": "webpack --mode=development --watch",
      "release": "webpack --mode=production",
      "publish": "npm run release && dotnet publish -c Release"
    },
    

    Zdefiniowane są następujące skrypty:

    • build: łączy zasoby po stronie klienta w trybie programowania i obserwuje zmiany plików. Obserwator plików powoduje ponowne wygenerowanie pakietu za każdym razem, gdy zmienia się plik projektu. Opcja mode wyłącza optymalizacje produkcyjne, takie jak drżenie drzewa i minimalizowanie. używać build tylko w środowisku programistycznym.
    • release: łączy zasoby po stronie klienta w trybie produkcyjnym.
    • publish: uruchamia release skrypt, aby powiązać zasoby po stronie klienta w trybie produkcyjnym. Wywołuje polecenie publikowania interfejsu wiersza polecenia platformy .NET w celu opublikowania aplikacji.
  5. Utwórz plik o nazwie webpack.config.js w katalogu głównym projektu z następującym kodem:

    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",
            }),
        ],
    };
    

    Powyższy plik konfiguruje proces kompilacji pakietu WebPack:

    • Właściwość output zastępuje wartość domyślną .dist Pakiet jest zamiast tego emitowany w wwwroot katalogu.
    • Tablica resolve.extensions obejmuje .js importowanie SignalR kodu JavaScript klienta.
  6. src Skopiuj katalog i jego zawartość z przykładowego projektu do katalogu głównego projektu. Katalog src zawiera następujące pliki:

    • index.html, który definiuje standardowy znacznik strony głównej:

      <!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, który udostępnia style CSS dla strony głównej:

      *,
      *::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, który konfiguruje kompilator TypeScript w celu utworzenia kodu JAVAScript zgodnego z językiem ECMAScript 5:

      {
        "compilerOptions": {
          "target": "es5"
        }
      }
      
    • index.ts:

      import * as signalR from "@microsoft/signalr";
      import "./css/main.css";
      
      const divMessages: HTMLDivElement = document.querySelector("#divMessages");
      const tbMessage: HTMLInputElement = document.querySelector("#tbMessage");
      const btnSend: HTMLButtonElement = document.querySelector("#btnSend");
      const username = new Date().getTime();
      
      const connection = new signalR.HubConnectionBuilder()
          .withUrl("/hub")
          .build();
      
      connection.on("messageReceived", (username: string, message: string) => {
        const m = document.createElement("div");
      
        m.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`;
      
        divMessages.appendChild(m);
        divMessages.scrollTop = divMessages.scrollHeight;
      });
      
      connection.start().catch((err) => document.write(err));
      
      tbMessage.addEventListener("keyup", (e: KeyboardEvent) => {
        if (e.key === "Enter") {
          send();
        }
      });
      
      btnSend.addEventListener("click", send);
      
      function send() {
        connection.send("newMessage", username, tbMessage.value)
          .then(() => (tbMessage.value = ""));
      }
      

      Powyższy kod pobiera odwołania do elementów DOM i dołącza dwa programy obsługi zdarzeń:

      • keyup: jest uruchamiany, gdy użytkownik wpisze w tbMessage polu tekstowym i wywołuje send funkcję, gdy użytkownik naciska klawisz Enter .
      • click: jest wyzwalany, gdy użytkownik wybierze przycisk Wyślij i wywoła send funkcję .

      Klasa HubConnectionBuilder tworzy nowego konstruktora do konfigurowania połączenia serwera. Funkcja withUrl konfiguruje adres URL centrum.

      SignalR umożliwia wymianę komunikatów między klientem a serwerem. Każda wiadomość ma określoną nazwę. Na przykład komunikaty o nazwie messageReceived mogą uruchamiać logikę odpowiedzialną za wyświetlanie nowego komunikatu w strefie komunikatów. Nasłuchiwanie określonego komunikatu on można wykonać za pośrednictwem funkcji . Można nasłuchiwać dowolnej liczby nazw wiadomości. Istnieje również możliwość przekazania parametrów do wiadomości, takich jak nazwa autora i zawartość odebranego komunikatu. Gdy klient otrzyma komunikat, zostanie utworzony nowy div element z nazwą autora i zawartością komunikatu w jego innerHTML atrybucie. Jest dodawany do głównego div elementu wyświetlającego komunikaty.

      Wysłanie komunikatu za pośrednictwem połączenia WebSockets wymaga wywołania send metody . Pierwszy parametr metody to nazwa komunikatu. Dane komunikatu zamieszkają inne parametry. W tym przykładzie komunikat zidentyfikowany jako newMessage jest wysyłany do serwera. Komunikat składa się z nazwy użytkownika i danych wejściowych użytkownika z pola tekstowego. Jeśli wysyłanie działa, wartość pola tekstowego zostanie wyczyszczone.

  7. Uruchom następujące polecenie w katalogu głównym projektu:

    npm i @microsoft/signalr @types/node
    

    Poprzednie polecenie instaluje:

    • SignalR Klient TypeScript, który umożliwia klientowi wysyłanie komunikatów do serwera.
    • Definicje typów języka TypeScript dla Node.js, które umożliwiają sprawdzanie czasu kompilacji typów Node.js.

Testowanie aplikacji

Upewnij się, że aplikacja działa z następującymi krokami:

  1. Uruchom pakiet webpack w release trybie. Za pomocą okna konsoli Menedżer pakietów uruchom następujące polecenie w katalogu głównym projektu.

    npm run release
    

    To polecenie generuje zasoby po stronie klienta, które mają być obsługiwane podczas uruchamiania aplikacji. Zasoby są umieszczane w folderze wwwroot .

    Pakiet Webpack wykonał następujące zadania:

    • Przeczyścił zawartość wwwroot katalogu.
    • Przekonwertowano język TypeScript na język JavaScript w procesie znanym jako transpilacja.
    • Wygenerowany kod JavaScript został wygenerowany w celu zmniejszenia rozmiaru pliku w procesie znanym jako minification.
    • Skopiowano przetworzone pliki JavaScript, CSS i HTML z src katalogu wwwroot .
    • W pliku wstrzyknął następujące elementy wwwroot/index.html :
      • <link> Tag, odwołując wwwroot/main.<hash>.css się do pliku. Ten tag jest umieszczany bezpośrednio przed tagiem zamykającym </head> .
      • <script> Tag, odwołując się do pliku minyfikowanegowwwroot/main.<hash>.js. Ten tag jest umieszczany natychmiast po tagu zamykającym </title> .
  2. Wybierz pozycję Debuguj>Rozpocznij bez debugowania, aby uruchomić aplikację w przeglądarce bez dołączania debugera. Plik wwwroot/index.html jest obsługiwany pod adresem https://localhost:<port>.

    Jeśli występują błędy kompilacji, spróbuj zamknąć i ponownie otworzyć rozwiązanie.

  3. Otwórz inne wystąpienie przeglądarki (dowolną przeglądarkę) i wklej adres URL na pasku adresu.

  4. Wybierz jedną z przeglądarek, wpisz coś w polu tekstowym Wiadomość , a następnie wybierz przycisk Wyślij . Unikatowa nazwa użytkownika i komunikat są wyświetlane na obu stronach natychmiast.

Komunikat wyświetlany w obu oknach przeglądarki

Następne kroki

Dodatkowe zasoby

W tym samouczku pokazano używanie pakietu Webpack w aplikacji internetowej ASP.NET Core SignalR w celu tworzenia pakietu i kompilowania klienta napisanego w języku TypeScript. Pakiet Webpack umożliwia deweloperom łączenie i tworzenie zasobów po stronie klienta aplikacji internetowej.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Tworzenie aplikacji ASP.NET Core SignalR
  • SignalR Konfigurowanie serwera
  • Konfigurowanie potoku kompilacji przy użyciu pakietu WebPack
  • SignalR Konfigurowanie klienta Języka TypeScript
  • Włączanie komunikacji między klientem a serwerem

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

  • Node.js za pomocą narzędzia npm

Tworzenie aplikacji internetowej platformy ASP.NET Core

Domyślnie program Visual Studio używa wersji narzędzia npm znalezionej w katalogu instalacyjnym. Aby skonfigurować program Visual Studio pod kątem wyszukiwania narzędzia npm w zmiennej środowiskowej PATH :

  1. Uruchom program Visual Studio. W oknie startowym wybierz pozycję Kontynuuj bez kodu.

  2. Przejdź do pozycji Narzędzia>Opcje>Projekty i rozwiązania>Web Package Management>Zewnętrzne narzędzia sieci Web.

  3. $(PATH) Wybierz wpis z listy. Wybierz strzałkę w górę, aby przenieść wpis na drugą pozycję na liście, a następnie wybierz przycisk OK:

    Konfiguracja programu Visual Studio.

Aby utworzyć nową aplikację internetową ASP.NET Core:

  1. Użyj opcji menu Plik>nowy>projekt i wybierz szablon ASP.NET Core Empty. Wybierz Dalej.
  2. Nadaj projektowi SignalRWebpacknazwę , a następnie wybierz pozycję Utwórz.
  3. Wybierz .NET 6.0 (Long Term Support) z listy rozwijanej Struktura . Wybierz pozycję Utwórz.

Dodaj pakiet NuGet Microsoft.TypeScript.MSBuild do projektu:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy węzeł projektu i wybierz polecenie Zarządzaj pakietami NuGet. Na karcie Przeglądaj wyszukajMicrosoft.TypeScript.MSBuild, a następnie wybierz pozycję Zainstaluj po prawej stronie, aby zainstalować pakiet.

Program Visual Studio dodaje pakiet NuGet w węźle Zależności w Eksplorator rozwiązań, włączając kompilację języka TypeScript w projekcie.

Konfigurowanie serwera

W tej sekcji skonfigurujesz aplikację internetową platformy ASP.NET Core do wysyłania i odbierania SignalR komunikatów.

  1. W Program.cspliku wywołaj metodę AddSignalR:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddSignalR();
    
  2. Ponownie w pliku Program.cswywołaj metodę UseDefaultFiles i UseStaticFiles:

    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseStaticFiles();
    

    Powyższy kod umożliwia serwerowi lokalizowanie i obsługę index.html pliku. Plik jest obsługiwany, czy użytkownik wprowadza pełny adres URL, czy główny adres URL aplikacji internetowej.

  3. Utwórz nowy katalog o nazwie Hubs w katalogu głównym SignalRWebpack/projektu , dla SignalR klasy centrum.

  4. Utwórz nowy plik z Hubs/ChatHub.csnastępującym kodem:

    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);
    }
    

    Powyższy kod rozgłasza odebrane komunikaty do wszystkich połączonych użytkowników po odebraniu ich przez serwer. Nie trzeba mieć ogólnej on metody odbierania wszystkich komunikatów. Wystarczy metoda o nazwie o nazwie komunikatu.

    W tym przykładzie klient TypeScript wysyła komunikat zidentyfikowany jako newMessage. Metoda języka C# NewMessage oczekuje danych wysyłanych przez klienta. Wywołanie jest wykonywane na SendAsync stronie Clients.All. Odebrane komunikaty są wysyłane do wszystkich klientów połączonych z koncentratorem.

  5. Dodaj następującą using instrukcję w górnej części, Program.cs aby rozwiązać ChatHub ten problem:

    using SignalRWebpack.Hubs;
    
  6. W Program.cspliku zamapuj /hubChatHub trasę na koncentrator. Zastąp kod wyświetlany Hello World! następującym kodem:

    app.MapHub<ChatHub>("/hub");
    

Konfigurowanie klienta

W tej sekcji utworzysz projekt Node.js , aby przekonwertować język TypeScript na język JavaScript i powiązać zasoby po stronie klienta, w tym html i CSS, przy użyciu pakietu WebPack.

  1. Uruchom następujące polecenie w katalogu głównym projektu, aby utworzyć package.json plik:

    npm init -y
    
  2. Dodaj wyróżnioną właściwość do package.json pliku i zapisz zmiany w pliku:

    {
      "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"
    }
    

    private Ustawienie właściwości w celu true uniemożliwinia instalowania pakietów ostrzeżeń w następnym kroku.

  3. Zainstaluj wymagane pakiety npm. Uruchom następujące polecenie z poziomu głównego projektu:

    npm i -D -E clean-webpack-plugin css-loader html-webpack-plugin mini-css-extract-plugin ts-loader typescript webpack webpack-cli
    

    Opcja -E wyłącza domyślne zachowanie narzędzia npm podczas pisania operatorów zakresu obsługi wersji semantycznych na package.json. Na przykład "webpack": "5.70.0" jest używany zamiast "webpack": "^5.70.0". Ta opcja uniemożliwia niezamierzone uaktualnienia do nowszych wersji pakietów.

    Aby uzyskać więcej informacji, zobacz dokumentację npm-install .

  4. Zastąp scripts właściwość package.json pliku następującym kodem:

    "scripts": {
      "build": "webpack --mode=development --watch",
      "release": "webpack --mode=production",
      "publish": "npm run release && dotnet publish -c Release"
    },
    

    Zdefiniowane są następujące skrypty:

    • build: łączy zasoby po stronie klienta w trybie programowania i obserwuje zmiany plików. Obserwator plików powoduje ponowne wygenerowanie pakietu za każdym razem, gdy zmienia się plik projektu. Opcja mode wyłącza optymalizacje produkcyjne, takie jak drżenie drzewa i minimalizowanie. używać build tylko w środowisku programistycznym.
    • release: łączy zasoby po stronie klienta w trybie produkcyjnym.
    • publish: uruchamia release skrypt, aby powiązać zasoby po stronie klienta w trybie produkcyjnym. Wywołuje polecenie publikowania interfejsu wiersza polecenia platformy .NET w celu opublikowania aplikacji.
  5. Utwórz plik o nazwie webpack.config.js w katalogu głównym projektu z następującym kodem:

    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",
        }),
      ],
    };
    

    Powyższy plik konfiguruje proces kompilacji pakietu WebPack:

    • Właściwość output zastępuje wartość domyślną .dist Pakiet jest zamiast tego emitowany w wwwroot katalogu.
    • Tablica resolve.extensions obejmuje .js importowanie SignalR kodu JavaScript klienta.
  6. src Skopiuj katalog i jego zawartość z przykładowego projektu do katalogu głównego projektu. Katalog src zawiera następujące pliki:

    • index.html, który definiuje standardowy znacznik strony głównej:

      <!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, który udostępnia style CSS dla strony głównej:

      *,
      *::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, który konfiguruje kompilator TypeScript w celu utworzenia kodu JAVAScript zgodnego z językiem ECMAScript 5:

      {
        "compilerOptions": {
          "target": "es5"
        }
      }
      
    • index.ts:

      import * as signalR from "@microsoft/signalr";
      import "./css/main.css";
      
      const divMessages: HTMLDivElement = document.querySelector("#divMessages");
      const tbMessage: HTMLInputElement = document.querySelector("#tbMessage");
      const btnSend: HTMLButtonElement = document.querySelector("#btnSend");
      const username = new Date().getTime();
      
      const connection = new signalR.HubConnectionBuilder()
          .withUrl("/hub")
          .build();
      
      connection.on("messageReceived", (username: string, message: string) => {
        const m = document.createElement("div");
      
        m.innerHTML = `<div class="message-author">${username}</div><div>${message}</div>`;
      
        divMessages.appendChild(m);
        divMessages.scrollTop = divMessages.scrollHeight;
      });
      
      connection.start().catch((err) => document.write(err));
      
      tbMessage.addEventListener("keyup", (e: KeyboardEvent) => {
        if (e.key === "Enter") {
          send();
        }
      });
      
      btnSend.addEventListener("click", send);
      
      function send() {
        connection.send("newMessage", username, tbMessage.value)
          .then(() => (tbMessage.value = ""));
      }
      

    Powyższy kod pobiera odwołania do elementów DOM i dołącza dwa programy obsługi zdarzeń:

    • keyup: jest uruchamiany, gdy użytkownik wpisze w tbMessage polu tekstowym i wywołuje send funkcję, gdy użytkownik naciska klawisz Enter .
    • click: jest wyzwalany, gdy użytkownik wybierze przycisk Wyślij i wywoła send funkcję .

    Klasa HubConnectionBuilder tworzy nowego konstruktora do konfigurowania połączenia serwera. Funkcja withUrl konfiguruje adres URL centrum.

    SignalR umożliwia wymianę komunikatów między klientem a serwerem. Każda wiadomość ma określoną nazwę. Na przykład komunikaty o nazwie messageReceived mogą uruchamiać logikę odpowiedzialną za wyświetlanie nowego komunikatu w strefie komunikatów. Nasłuchiwanie określonego komunikatu on można wykonać za pośrednictwem funkcji . Można nasłuchiwać dowolnej liczby nazw wiadomości. Istnieje również możliwość przekazania parametrów do wiadomości, takich jak nazwa autora i zawartość odebranego komunikatu. Gdy klient otrzyma komunikat, zostanie utworzony nowy div element z nazwą autora i zawartością komunikatu w jego innerHTML atrybucie. Jest dodawany do głównego div elementu wyświetlającego komunikaty.

    Wysłanie komunikatu za pośrednictwem połączenia WebSockets wymaga wywołania send metody . Pierwszy parametr metody to nazwa komunikatu. Dane komunikatu zamieszkają inne parametry. W tym przykładzie komunikat zidentyfikowany jako newMessage jest wysyłany do serwera. Komunikat składa się z nazwy użytkownika i danych wejściowych użytkownika z pola tekstowego. Jeśli wysyłanie działa, wartość pola tekstowego zostanie wyczyszczone.

  7. Uruchom następujące polecenie w katalogu głównym projektu:

    npm i @microsoft/signalr @types/node
    

    Poprzednie polecenie instaluje:

    • SignalR Klient TypeScript, który umożliwia klientowi wysyłanie komunikatów do serwera.
    • Definicje typów języka TypeScript dla Node.js, które umożliwiają sprawdzanie czasu kompilacji typów Node.js.

Testowanie aplikacji

Upewnij się, że aplikacja działa z następującymi krokami:

  1. Uruchom pakiet webpack w release trybie. Za pomocą okna konsoli Menedżer pakietów uruchom następujące polecenie w katalogu głównym projektu. Jeśli nie jesteś w katalogu głównym projektu, wprowadź cd SignalRWebpack przed wprowadzeniem polecenia.

    npm run release
    

    To polecenie generuje zasoby po stronie klienta, które mają być obsługiwane podczas uruchamiania aplikacji. Zasoby są umieszczane w folderze wwwroot .

    Pakiet Webpack wykonał następujące zadania:

    • Przeczyścił zawartość wwwroot katalogu.
    • Przekonwertowano język TypeScript na język JavaScript w procesie znanym jako transpilacja.
    • Wygenerowany kod JavaScript został wygenerowany w celu zmniejszenia rozmiaru pliku w procesie znanym jako minification.
    • Skopiowano przetworzone pliki JavaScript, CSS i HTML z src katalogu wwwroot .
    • W pliku wstrzyknął następujące elementy wwwroot/index.html :
      • <link> Tag, odwołując wwwroot/main.<hash>.css się do pliku. Ten tag jest umieszczany bezpośrednio przed tagiem zamykającym </head> .
      • <script> Tag, odwołując się do pliku minyfikowanegowwwroot/main.<hash>.js. Ten tag jest umieszczany natychmiast po tagu zamykającym </title> .
  2. Wybierz pozycję Debuguj>Rozpocznij bez debugowania, aby uruchomić aplikację w przeglądarce bez dołączania debugera. Plik wwwroot/index.html jest obsługiwany pod adresem https://localhost:<port>.

    Jeśli wystąpią błędy kompilacji, spróbuj zamknąć i ponownie otworzyć rozwiązanie.

  3. Otwórz inne wystąpienie przeglądarki (dowolną przeglądarkę) i wklej adres URL na pasku adresu.

  4. Wybierz jedną z przeglądarek, wpisz coś w polu tekstowym Wiadomość , a następnie wybierz przycisk Wyślij . Unikatowa nazwa użytkownika i komunikat są wyświetlane na obu stronach natychmiast.

Komunikat wyświetlany w obu oknach przeglądarki

Następne kroki

Dodatkowe zasoby

W tym samouczku pokazano używanie pakietu Webpack w aplikacji internetowej ASP.NET Core SignalR w celu tworzenia pakietu i kompilowania klienta napisanego w języku TypeScript. Pakiet Webpack umożliwia deweloperom łączenie i tworzenie zasobów po stronie klienta aplikacji internetowej.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Tworzenie szkieletu początkowej aplikacji ASP.NET Core SignalR
  • SignalR Konfigurowanie klienta Języka TypeScript
  • Konfigurowanie potoku kompilacji przy użyciu pakietu WebPack
  • SignalR Konfigurowanie serwera
  • Włączanie komunikacji między klientem a serwerem

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

Tworzenie aplikacji internetowej platformy ASP.NET Core

Skonfiguruj program Visual Studio, aby wyszukać plik npm w zmiennej środowiskowej PATH . Domyślnie program Visual Studio używa wersji narzędzia npm znalezionej w katalogu instalacyjnym. Wykonaj następujące instrukcje w programie Visual Studio:

  1. Uruchom program Visual Studio. W oknie startowym wybierz pozycję Kontynuuj bez kodu.

  2. Przejdź do pozycji Narzędzia>Opcje>Projekty i rozwiązania>Web Package Management>Zewnętrzne narzędzia sieci Web.

  3. Wybierz wpis $(PATH) z listy. Wybierz strzałkę w górę, aby przenieść wpis na drugą pozycję na liście, a następnie wybierz przycisk OK.

    Konfiguracja programu Visual Studio.

Konfiguracja programu Visual Studio została ukończona.

  1. Użyj opcji menu Plik>nowy>projekt i wybierz szablon aplikacji internetowej ASP.NET Core. Wybierz Dalej.
  2. Nadaj projektowi nazwę *SignalRWebPac'' i wybierz pozycję Utwórz.
  3. Z listy rozwijanej platformy docelowej wybierz pozycję .NET Core i wybierz pozycję ASP.NET Core 3.1 z listy rozwijanej selektora platformy. Wybierz szablon Pusty, a następnie wybierz pozycję Utwórz.

Microsoft.TypeScript.MSBuild Dodaj pakiet do projektu:

  1. W Eksplorator rozwiązań (okienko po prawej stronie) kliknij prawym przyciskiem myszy węzeł projektu i wybierz pozycję Zarządzaj pakietami NuGet. Na karcie Przeglądaj wyszukaj ciąg Microsoft.TypeScript.MSBuild, a następnie kliknij pozycję Zainstaluj po prawej stronie, aby zainstalować pakiet.

Program Visual Studio dodaje pakiet NuGet w węźle Zależności w Eksplorator rozwiązań, włączając kompilację języka TypeScript w projekcie.

Konfigurowanie pakietu Webpack i języka TypeScript

Poniższe kroki umożliwiają skonfigurowanie konwersji języka TypeScript na język JavaScript i łączenie zasobów po stronie klienta.

  1. Uruchom następujące polecenie w katalogu głównym projektu, aby utworzyć package.json plik:

    npm init -y
    
  2. Dodaj wyróżnioną właściwość do package.json pliku i zapisz zmiany w pliku:

    {
      "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"
    }
    

    private Ustawienie właściwości w celu true uniemożliwinia instalowania pakietów ostrzeżeń w następnym kroku.

  3. Zainstaluj wymagane pakiety npm. Uruchom następujące polecenie z poziomu głównego projektu:

    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
    

    Niektóre szczegóły polecenia, które należy zwrócić uwagę:

    • Numer wersji jest zgodny z znakiem @ dla każdej nazwy pakietu. Narzędzie npm instaluje te konkretne wersje pakietów.
    • Opcja -E wyłącza domyślne zachowanie narzędzia npm podczas pisania operatorów zakresu obsługi wersji semantycznych do *pakietujson. Na przykład "webpack": "4.41.5" jest używany zamiast "webpack": "^4.41.5". Ta opcja uniemożliwia niezamierzone uaktualnienia do nowszych wersji pakietów.

    Aby uzyskać więcej informacji, zobacz dokumentację npm-install .

  4. Zastąp scripts właściwość package.json pliku następującym kodem:

    "scripts": {
      "build": "webpack --mode=development --watch",
      "release": "webpack --mode=production",
      "publish": "npm run release && dotnet publish -c Release"
    },
    

    Niektóre wyjaśnienia skryptów:

    • build: łączy zasoby po stronie klienta w trybie programowania i obserwuje zmiany plików. Obserwator plików powoduje ponowne wygenerowanie pakietu za każdym razem, gdy zmienia się plik projektu. Opcja mode wyłącza optymalizacje produkcyjne, takie jak drżenie drzewa i minimalizowanie. Używaj build tylko w programowania.
    • release: łączy zasoby po stronie klienta w trybie produkcyjnym.
    • publish: uruchamia release skrypt, aby powiązać zasoby po stronie klienta w trybie produkcyjnym. Wywołuje polecenie publikowania interfejsu wiersza polecenia platformy .NET Core w celu opublikowania aplikacji.
  5. Utwórz plik o nazwie webpack.config.js, w katalogu głównym projektu z następującym kodem:

    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"
            })
        ]
    };
    

    Powyższy plik konfiguruje kompilację pakietu webpack. Niektóre szczegóły konfiguracji, które należy zwrócić uwagę:

    • Właściwość output zastępuje wartość domyślną .dist Pakiet jest zamiast tego emitowany w wwwroot katalogu.
    • Tablica resolve.extensions obejmuje .js importowanie SignalR kodu JavaScript klienta.
  6. Utwórz nowy katalog src w katalogu głównym projektu, aby przechowywać zasoby po stronie klienta projektu.

  7. Utwórz src/index.html za pomocą następującego znacznika.

    <!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>
    

    Powyższy kod HTML definiuje standardowy znacznik strony głównej.

  8. Utwórz nowy katalog src/css . Jego celem jest przechowywanie plików projektu .css .

  9. Utwórz src/css/main.css przy użyciu następującego pliku CSS:

    *, *::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;
    }
    

    main.css Poprzednie style pliku są stylami aplikacji.

  10. Utwórz src/tsconfig.json przy użyciu następującego JSpolecenia ON:

    {
      "compilerOptions": {
        "target": "es5"
      }
    }
    

    Powyższy kod konfiguruje kompilator Języka TypeScript w celu utworzenia kodu JavaScript zgodnego z językiem ECMAScript 5.

  11. Utwórz src/index.ts za pomocą następującego kodu:

    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() {
    }
    

    Powyższy kod TypeScript pobiera odwołania do elementów DOM i dołącza dwa programy obsługi zdarzeń:

    • keyup: to zdarzenie jest uruchamiane, gdy użytkownik wpisze je w polu tekstowym tbMessage. Funkcja jest wywoływana send , gdy użytkownik naciska klawisz Enter .
    • click: to zdarzenie jest uruchamiane, gdy użytkownik wybierze przycisk Wyślij . Wywołanie funkcji send.

Konfigurowanie aplikacji

  1. W Startup.Configurepliku dodaj wywołania do UseDefaultFiles(IApplicationBuilder) i UseStaticFiles(IApplicationBuilder).

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        
        app.UseRouting();
        app.UseDefaultFiles();
        app.UseStaticFiles();
        
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<ChatHub>("/hub");
        });
            
    }
    

    Powyższy kod umożliwia serwerowi lokalizowanie i obsługę index.html pliku. Plik jest obsługiwany, czy użytkownik wprowadza pełny adres URL, czy główny adres URL aplikacji internetowej.

  2. Na końcu Startup.Configureelementu zamapuj /hub na trasę do ChatHub koncentratora. Zastąp kod wyświetlający ciąg Hello World! następującym wierszem:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/hub");
    });
    
  3. W Startup.ConfigureServicespliku wywołaj metodę AddSignalR.

    services.AddSignalR();
    
  4. Utwórz nowy katalog o nazwie Hubs w głównym SignalRprojekcie WebPack/ do przechowywania SignalR centrum.

  5. Utwórz centrum Hubs/ChatHub.cs przy użyciu następującego kodu:

    using Microsoft.AspNetCore.SignalR;
    using System.Threading.Tasks;
    
    namespace SignalRWebPack.Hubs
    {
        public class ChatHub : Hub
        {
        }
    }
    
  6. Dodaj następującą using instrukcję w górnej części pliku, Startup.cs aby rozwiązać ChatHub ten problem:

    using SignalRWebPack.Hubs;
    

Włączanie komunikacji klienta i serwera

Aplikacja wyświetla obecnie podstawowy formularz do wysyłania komunikatów, ale nie jest jeszcze funkcjonalny. Serwer nasłuchuje określonej trasy, ale nie wykonuje żadnych czynności z wysłanymi komunikatami.

  1. Uruchom następujące polecenie w katalogu głównym projektu:

    npm i @microsoft/signalr @types/node
    

    Poprzednie polecenie instaluje:

    • SignalR Klient TypeScript, który umożliwia klientowi wysyłanie komunikatów do serwera.
    • Definicje typów języka TypeScript dla Node.js, które umożliwiają sprawdzanie czasu kompilacji typów Node.js.
  2. Dodaj wyróżniony kod do src/index.ts pliku:

    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() {
    }
    

    Powyższy kod obsługuje odbieranie komunikatów z serwera. Klasa HubConnectionBuilder tworzy nowego konstruktora do konfigurowania połączenia serwera. Funkcja withUrl konfiguruje adres URL centrum.

    SignalR umożliwia wymianę komunikatów między klientem a serwerem. Każda wiadomość ma określoną nazwę. Na przykład komunikaty o nazwie messageReceived mogą uruchamiać logikę odpowiedzialną za wyświetlanie nowego komunikatu w strefie komunikatów. Nasłuchiwanie określonego komunikatu on można wykonać za pośrednictwem funkcji . Można nasłuchiwać dowolnej liczby nazw wiadomości. Istnieje również możliwość przekazania parametrów do wiadomości, takich jak nazwa autora i zawartość odebranego komunikatu. Gdy klient otrzyma komunikat, zostanie utworzony nowy div element z nazwą autora i zawartością komunikatu w jego innerHTML atrybucie. Jest dodawany do głównego div elementu wyświetlającego komunikaty.

  3. Teraz, gdy klient może odebrać komunikat, skonfiguruj go do wysyłania komunikatów. Dodaj wyróżniony kod do src/index.ts pliku:

    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 = "");
    }
    

    Wysłanie komunikatu za pośrednictwem połączenia WebSockets wymaga wywołania send metody . Pierwszy parametr metody to nazwa komunikatu. Dane komunikatu zamieszkają inne parametry. W tym przykładzie komunikat zidentyfikowany jako newMessage jest wysyłany do serwera. Komunikat składa się z nazwy użytkownika i danych wejściowych użytkownika z pola tekstowego. Jeśli wysyłanie działa, wartość pola tekstowego zostanie wyczyszczone.

  4. Dodaj metodę NewMessage do klasy ChatHub:

    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);
            }
        }
    }
    

    Powyższy kod rozgłasza odebrane komunikaty do wszystkich połączonych użytkowników po odebraniu ich przez serwer. Nie trzeba mieć ogólnej on metody odbierania wszystkich komunikatów. Metoda o nazwie po nazwie komunikatu wystarczy.

    W tym przykładzie klient TypeScript wysyła komunikat zidentyfikowany jako newMessage. Metoda języka C# NewMessage oczekuje danych wysyłanych przez klienta. Wywołanie jest wykonywane na SendAsync stronie Clients.All. Odebrane komunikaty są wysyłane do wszystkich klientów połączonych z koncentratorem.

Testowanie aplikacji

Upewnij się, że aplikacja działa z następującymi krokami.

  1. Uruchom pakiet WebPack w trybie wydania . Za pomocą okna konsoli Menedżer pakietów uruchom następujące polecenie w katalogu głównym projektu. Jeśli nie jesteś w katalogu głównym projektu, wprowadź cd SignalRWebPack przed wprowadzeniem polecenia.

    npm run release
    

    To polecenie generuje zasoby po stronie klienta, które mają być obsługiwane podczas uruchamiania aplikacji. Zasoby są umieszczane w folderze wwwroot .

    Pakiet Webpack wykonał następujące zadania:

    • Przeczyścił zawartość wwwroot katalogu.
    • Przekonwertowano język TypeScript na język JavaScript w procesie znanym jako transpilacja.
    • Wygenerowany kod JavaScript został wygenerowany w celu zmniejszenia rozmiaru pliku w procesie znanym jako minification.
    • Skopiowano przetworzone pliki JavaScript, CSS i HTML z src katalogu wwwroot .
    • W pliku wstrzyknął następujące elementy wwwroot/index.html :
      • <link> Tag, odwołując wwwroot/main.<hash>.css się do pliku. Ten tag jest umieszczany bezpośrednio przed tagiem zamykającym </head> .
      • <script> Tag, odwołując się do pliku minyfikowanegowwwroot/main.<hash>.js. Ten tag jest umieszczany natychmiast po tagu zamykającym </title> .
  2. Wybierz pozycję Debuguj>Rozpocznij bez debugowania, aby uruchomić aplikację w przeglądarce bez dołączania debugera. Plik wwwroot/index.html jest obsługiwany pod adresem http://localhost:<port_number>.

    Jeśli wystąpią błędy kompilacji, spróbuj zamknąć i ponownie otworzyć rozwiązanie.

  3. Otwórz inne wystąpienie przeglądarki (dowolną przeglądarkę). Wklej adres URL na pasku adresu.

  4. Wybierz jedną z przeglądarek, wpisz coś w polu tekstowym Wiadomość , a następnie wybierz przycisk Wyślij . Unikatowa nazwa użytkownika i komunikat są wyświetlane na obu stronach natychmiast.

Komunikat wyświetlany w obu oknach przeglądarki

Dodatkowe zasoby

W tym samouczku pokazano używanie pakietu Webpack w aplikacji internetowej ASP.NET Core SignalR w celu tworzenia pakietu i kompilowania klienta napisanego w języku TypeScript. Pakiet Webpack umożliwia deweloperom łączenie i tworzenie zasobów po stronie klienta aplikacji internetowej.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Tworzenie szkieletu początkowej aplikacji ASP.NET Core SignalR
  • SignalR Konfigurowanie klienta Języka TypeScript
  • Konfigurowanie potoku kompilacji przy użyciu pakietu WebPack
  • SignalR Konfigurowanie serwera
  • Włączanie komunikacji między klientem a serwerem

Wyświetl lub pobierz przykładowy kod (jak pobrać)

Wymagania wstępne

Tworzenie aplikacji internetowej platformy ASP.NET Core

Skonfiguruj program Visual Studio, aby wyszukać plik npm w zmiennej środowiskowej PATH . Domyślnie program Visual Studio używa wersji narzędzia npm znalezionej w katalogu instalacyjnym. Wykonaj następujące instrukcje w programie Visual Studio:

  1. Przejdź do pozycji Narzędzia>Opcje>Projekty i rozwiązania>Web Package Management>Zewnętrzne narzędzia sieci Web.

  2. Wybierz wpis $(PATH) z listy. Wybierz strzałkę w górę, aby przenieść wpis na drugą pozycję na liście.

    Konfiguracja programu Visual Studio

Konfiguracja programu Visual Studio została ukończona. Nadszedł czas, aby utworzyć projekt.

  1. Użyj opcji menu Plik>nowy>projekt i wybierz szablon aplikacji internetowej ASP.NET Core.
  2. Nadaj projektowi nazwę *SignalRWebPack', a następnie wybierz pozycję Utwórz.
  3. Z listy rozwijanej platformy docelowej wybierz pozycję .NET Core i wybierz pozycję ASP.NET Core 2.2 z listy rozwijanej selektora platformy. Wybierz szablon Pusty, a następnie wybierz pozycję Utwórz.

Konfigurowanie pakietu Webpack i języka TypeScript

Poniższe kroki umożliwiają skonfigurowanie konwersji języka TypeScript na język JavaScript i łączenie zasobów po stronie klienta.

  1. Uruchom następujące polecenie w katalogu głównym projektu, aby utworzyć package.json plik:

    npm init -y
    
  2. Dodaj wyróżnioną właściwość do package.json pliku:

    {
      "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"
    }
    

    private Ustawienie właściwości w celu true uniemożliwinia instalowania pakietów ostrzeżeń w następnym kroku.

  3. Zainstaluj wymagane pakiety npm. Uruchom następujące polecenie z poziomu głównego projektu:

    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
    

    Niektóre szczegóły polecenia, które należy zwrócić uwagę:

    • Numer wersji jest zgodny z znakiem @ dla każdej nazwy pakietu. Narzędzie npm instaluje te konkretne wersje pakietów.
    • Opcja -E wyłącza domyślne zachowanie narzędzia npm podczas pisania operatorów zakresu obsługi wersji semantycznych do *pakietujson. Na przykład "webpack": "4.29.3" jest używany zamiast "webpack": "^4.29.3". Ta opcja uniemożliwia niezamierzone uaktualnienia do nowszych wersji pakietów.

    Aby uzyskać więcej informacji, zobacz dokumentację npm-install .

  4. Zastąp scripts właściwość package.json pliku następującym kodem:

    "scripts": {
      "build": "webpack --mode=development --watch",
      "release": "webpack --mode=production",
      "publish": "npm run release && dotnet publish -c Release"
    },
    

    Niektóre wyjaśnienia skryptów:

    • build: łączy zasoby po stronie klienta w trybie programowania i obserwuje zmiany plików. Obserwator plików powoduje ponowne wygenerowanie pakietu za każdym razem, gdy zmienia się plik projektu. Opcja mode wyłącza optymalizacje produkcyjne, takie jak drżenie drzewa i minimalizowanie. Używaj build tylko w programowania.
    • release: łączy zasoby po stronie klienta w trybie produkcyjnym.
    • publish: uruchamia release skrypt, aby powiązać zasoby po stronie klienta w trybie produkcyjnym. Wywołuje polecenie publikowania interfejsu wiersza polecenia platformy .NET Core w celu opublikowania aplikacji.
  5. Utwórz plik o nazwie*webpack.config.js w katalogu głównym projektu z następującym kodem:

    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"
            })
        ]
    };
    

    Powyższy plik konfiguruje kompilację pakietu webpack. Niektóre szczegóły konfiguracji, które należy zwrócić uwagę:

    • Właściwość output zastępuje wartość domyślną .dist Pakiet jest zamiast tego emitowany w wwwroot katalogu.
    • Tablica resolve.extensions obejmuje .js importowanie SignalR kodu JavaScript klienta.
  6. Utwórz nowy katalog src w katalogu głównym projektu, aby przechowywać zasoby po stronie klienta projektu.

  7. Utwórz src/index.html za pomocą następującego znacznika.

    <!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>
    

    Powyższy kod HTML definiuje standardowy znacznik strony głównej.

  8. Utwórz nowy katalog src/css . Jego celem jest przechowywanie plików projektu .css .

  9. Utwórz src/css/main.css za pomocą następującego znacznika:

    *, *::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;
    }
    

    main.css Poprzednie style pliku są stylami aplikacji.

  10. Utwórz src/tsconfig.json przy użyciu następującego JSpolecenia ON:

    {
      "compilerOptions": {
        "target": "es5"
      }
    }
    

    Powyższy kod konfiguruje kompilator Języka TypeScript w celu utworzenia kodu JavaScript zgodnego z językiem ECMAScript 5.

  11. Utwórz src/index.ts za pomocą następującego kodu:

    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() {
    }
    

    Powyższy kod TypeScript pobiera odwołania do elementów DOM i dołącza dwa programy obsługi zdarzeń:

    • keyup: to zdarzenie jest uruchamiane, gdy użytkownik wpisze je w polu tekstowym tbMessage . Funkcja jest wywoływana send , gdy użytkownik naciska klawisz Enter .
    • click: to zdarzenie jest uruchamiane, gdy użytkownik wybierze przycisk Wyślij . Wywołanie funkcji send.

Konfigurowanie aplikacji ASP.NET Core

  1. Kod podany w metodzie Startup.Configure wyświetla komunikat Hello World!. Zastąp app.Run wywołanie metody wywołaniami metod i UseDefaultFiles(IApplicationBuilder)UseStaticFiles(IApplicationBuilder).

    app.UseDefaultFiles();
    app.UseStaticFiles();
    

    Powyższy kod umożliwia serwerowi lokalizowanie i obsługę index.html pliku, niezależnie od tego, czy użytkownik wprowadza pełny adres URL, czy główny adres URL aplikacji internetowej.

  2. Wywołaj metodę AddSignalR w pliku Startup.ConfigureServices. SignalR Dodaje usługi do projektu.

    services.AddSignalR();
    
  3. Mapuj trasę /hub na ChatHub koncentrator. Dodaj następujące wiersze na końcu elementu Startup.Configure:

    app.UseSignalR(options =>
    {
        options.MapHub<ChatHub>("/hub");
    });
    
  4. Utwórz nowy katalog o nazwie Hubs w katalogu głównym projektu. Jego celem jest przechowywanie SignalR koncentratora, który jest tworzony w następnym kroku.

  5. Utwórz centrum Hubs/ChatHub.cs przy użyciu następującego kodu:

    using Microsoft.AspNetCore.SignalR;
    using System.Threading.Tasks;
    
    namespace SignalRWebPack.Hubs
    {
        public class ChatHub : Hub
        {
        }
    }
    
  6. Dodaj następujący kod w górnej części pliku, Startup.cs aby rozwiązać problem z odwołaniem ChatHub :

    using SignalRWebPack.Hubs;
    

Włączanie komunikacji klienta i serwera

Aplikacja wyświetla obecnie prosty formularz do wysyłania komunikatów. Nic się nie dzieje, gdy próbujesz to zrobić. Serwer nasłuchuje określonej trasy, ale nie wykonuje żadnych czynności z wysłanymi komunikatami.

  1. Uruchom następujące polecenie w katalogu głównym projektu:

    npm install @aspnet/signalr
    

    Poprzednie polecenie instaluje SignalR klienta TypeScript, który umożliwia klientowi wysyłanie komunikatów do serwera.

  2. Dodaj wyróżniony kod do src/index.ts pliku:

    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() {
    }
    

    Powyższy kod obsługuje odbieranie komunikatów z serwera. Klasa HubConnectionBuilder tworzy nowego konstruktora do konfigurowania połączenia serwera. Funkcja withUrl konfiguruje adres URL centrum.

    SignalR umożliwia wymianę komunikatów między klientem a serwerem. Każda wiadomość ma określoną nazwę. Na przykład komunikaty o nazwie messageReceived mogą uruchamiać logikę odpowiedzialną za wyświetlanie nowego komunikatu w strefie komunikatów. Nasłuchiwanie określonego komunikatu on można wykonać za pośrednictwem funkcji . Możesz nasłuchiwać dowolnej liczby nazw wiadomości. Istnieje również możliwość przekazania parametrów do wiadomości, takich jak nazwa autora i zawartość odebranego komunikatu. Gdy klient otrzyma komunikat, zostanie utworzony nowy div element z nazwą autora i zawartością komunikatu w jego innerHTML atrybucie. Nowy komunikat jest dodawany do głównego div elementu wyświetlającego komunikaty.

  3. Teraz, gdy klient może odebrać komunikat, skonfiguruj go do wysyłania komunikatów. Dodaj wyróżniony kod do src/index.ts pliku:

    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 = "");
    }
    

    Wysłanie komunikatu za pośrednictwem połączenia WebSockets wymaga wywołania send metody . Pierwszy parametr metody to nazwa komunikatu. Dane komunikatu zamieszkają inne parametry. W tym przykładzie komunikat zidentyfikowany jako newMessage jest wysyłany do serwera. Komunikat składa się z nazwy użytkownika i danych wejściowych użytkownika z pola tekstowego. Jeśli wysyłanie działa, wartość pola tekstowego zostanie wyczyszczone.

  4. Dodaj metodę NewMessage do klasy ChatHub:

    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);
            }
        }
    }
    

    Powyższy kod rozgłasza odebrane komunikaty do wszystkich połączonych użytkowników po odebraniu ich przez serwer. Nie trzeba mieć ogólnej on metody odbierania wszystkich komunikatów. Metoda o nazwie po nazwie komunikatu wystarczy.

    W tym przykładzie klient TypeScript wysyła komunikat zidentyfikowany jako newMessage. Metoda języka C# NewMessage oczekuje danych wysyłanych przez klienta. Wywołanie jest wykonywane na SendAsync stronie Clients.All. Odebrane komunikaty są wysyłane do wszystkich klientów połączonych z koncentratorem.

Testowanie aplikacji

Upewnij się, że aplikacja działa z następującymi krokami.

  1. Uruchom pakiet WebPack w trybie wydania . Za pomocą okna konsoli Menedżer pakietów uruchom następujące polecenie w katalogu głównym projektu. Jeśli nie jesteś w katalogu głównym projektu, wprowadź cd SignalRWebPack przed wprowadzeniem polecenia.

    npm run release
    

    To polecenie generuje zasoby po stronie klienta, które mają być obsługiwane podczas uruchamiania aplikacji. Zasoby są umieszczane w folderze wwwroot .

    Pakiet Webpack wykonał następujące zadania:

    • Przeczyścił zawartość wwwroot katalogu.
    • Przekonwertowano język TypeScript na język JavaScript w procesie znanym jako transpilacja.
    • Wygenerowany kod JavaScript został wygenerowany w celu zmniejszenia rozmiaru pliku w procesie znanym jako minification.
    • Skopiowano przetworzone pliki JavaScript, CSS i HTML z src katalogu wwwroot .
    • W pliku wstrzyknął następujące elementy wwwroot/index.html :
      • <link> Tag, odwołując wwwroot/main.<hash>.css się do pliku. Ten tag jest umieszczany bezpośrednio przed tagiem zamykającym </head> .
      • <script> Tag, odwołując się do pliku minyfikowanegowwwroot/main.<hash>.js. Ten tag jest umieszczany natychmiast po tagu zamykającym </title> .
  2. Wybierz pozycję Debuguj>Rozpocznij bez debugowania, aby uruchomić aplikację w przeglądarce bez dołączania debugera. Plik wwwroot/index.html jest obsługiwany pod adresem http://localhost:<port_number>.

  3. Otwórz inne wystąpienie przeglądarki (dowolną przeglądarkę). Wklej adres URL na pasku adresu.

  4. Wybierz jedną z przeglądarek, wpisz coś w polu tekstowym Wiadomość , a następnie wybierz przycisk Wyślij . Unikatowa nazwa użytkownika i komunikat są wyświetlane na obu stronach natychmiast.

Komunikat wyświetlany w obu oknach przeglądarki

Dodatkowe zasoby