SignalRTypeScript ve webpack ile ASP.NET Core kullanma

, Sébastien Sougnez ve Scott Ade tarafından

WebPack , geliştiricilerin bir Web uygulamasının istemci tarafı kaynaklarını paketleyip oluşturmalarına olanak sağlar. bu öğretici SignalR , istemcisinin TypeScript'te yazıldığı bir ASP.NET Core web uygulamasında webpack 'in kullanımını gösterir.

Bu öğreticide şunların nasıl yapıldığını öğreneceksiniz:

  • bir başlatıcı ASP.NET Core SignalR uygulaması oluşturma
  • SignalRTypeScript istemcisini yapılandırma
  • WebPack kullanarak derleme işlem hattı yapılandırma
  • Sunucuyu yapılandırma SignalR
  • İstemci ve sunucu arasındaki iletişimi etkinleştir

Örnek kodu görüntüleme veya indirme (nasıl indirileceği)

Önkoşullar

ASP.NET Core web uygulaması oluşturma

PATH ortam değişkeninde npm 'yi aramak için Visual Studio yapılandırın. varsayılan olarak Visual Studio, yükleme dizininde bulunan npm sürümünü kullanır. Visual Studio şu yönergeleri izleyin:

  1. Visual Studio başlatın. Başlangıç penceresinde, kod olmadan devam et' i seçin.

  2. Araçlar > Seçenekler > Projeler ve çözümler > Web paket yönetimi > dış Web araçları' na gidin.

  3. Listeden $ (yol) girişini seçin. Yukarı oka tıklayarak girişi listedeki ikinci konuma taşıyın ve Tamam' ı seçin.

    Visual Studio Yapılandırmada

Visual Studio yapılandırması tamamlanmıştır.

  1. dosya > yeni > Project menü seçeneğini kullanın ve ASP.NET Core Web uygulaması şablonunu seçin. İleri’yi seçin.
  2. Projeyi SignalR WebPack olarak adlandırın ve Oluştur' u seçin.
  3. hedef çerçeve açılır listesinden .net Core ' u seçin ve çerçeve seçicisi açılır listesinden ASP.NET Core 3,1 ' ı seçin. Boş şablonu seçin ve Oluştur' u seçin.

Microsoft.TypeScript.MSBuildPaketi projeye ekleyin:

  1. Çözüm Gezgini (sağ bölme) içinde, proje düğümüne sağ tıklayın ve NuGet paketlerini yönet' i seçin. Araştır sekmesine gidin Microsoft.TypeScript.MSBuild ve ardından paketi yüklemek için sağ tarafta bulunan ara ' yı tıklatın.

Visual Studio, NuGet paketini Çözüm Gezgini' deki bağımlılıklar düğümü altına ekler ve projede TypeScript derlemesini etkinleştirir.

WebPack ve TypeScript yapılandırma

Aşağıdaki adımlar, TypeScript 'in JavaScript 'e dönüştürülmesini ve istemci tarafı kaynaklarını paketlemeyi yapılandırır.

  1. Dosyasında bir package.js oluşturmak için proje kökünde aşağıdaki komutu çalıştırın:

    npm init -y
    
  2. Vurgulanan özelliği dosyadaki package.js ekleyin ve dosya değişikliklerini kaydedin:

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

    Özelliği, bir private true sonraki adımda paket yükleme uyarılarını engelleyecek şekilde ayarlanıyor.

  3. Gerekli NPM paketlerini yükler. Proje kökünden aşağıdaki komutu çalıştırın:

    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
    

    Aklınızda bazı komut ayrıntıları:

    • Sürüm numarası @ her paket adı için işareti izler. NPM bu özel paket sürümlerini yüklüyor.
    • Bu -E seçenek, NPM 'nin anlam sürümü oluşturma aralığı işleçlerini package.js için varsayılan davranışını devre dışı bırakır. Örneğin, "webpack": "4.41.5" yerine kullanılır "webpack": "^4.41.5" . Bu seçenek, daha yeni paket sürümlerine istenmeden yükseltme yapılmasını engeller.

    Daha fazla ayrıntı için bkz. NPM-Install docs.

  4. scriptsDosyadaki package.js özelliğini aşağıdaki kodla değiştirin:

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

    Betiklerin bazı açıklamaları:

    • build: İstemci tarafı kaynaklarını geliştirme modunda paketler ve dosya değişikliklerini izler. Dosya izleyici, bir proje dosyası her değiştiğinde paketin yeniden oluşturulmasına neden olur. modeSeçeneği, Tree gerçekleşmesi ve minbirleşme gibi üretim iyileştirmeleri devre dışı bırakır. Yalnızca build geliştirme aşamasında kullanın.
    • release: İstemci tarafı kaynaklarını üretim modunda paketlayın.
    • publish: release İstemci tarafı kaynaklarını üretim modunda paketleyip betiği çalıştırır. Uygulamayı yayımlamak için .NET Core CLI Publish komutunu çağırır.
  5. Proje kökünde aşağıdaki kodla webpack.config.js adlı bir dosya oluşturun:

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

    Yukarıdaki dosya Web paketi derlemesini yapılandırır. Aklınızda bazı yapılandırma ayrıntıları:

    • outputÖzelliği, dağ'ın varsayılan değerini geçersiz kılar. Paket, Wwwroot dizininde yayınlanır.
    • resolve.extensionsDizi, Istemci JavaScript 'i içeri aktarmak için .js içerir SignalR .
  6. Projenin istemci tarafı varlıklarını depolamak için proje kökünde yeni bir src dizini oluşturun.

  7. Aşağıdaki işaretle src/index.html oluşturun.

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

    Önceki HTML, giriş sayfasının ortak işaretlemesini tanımlar.

  8. Yeni bir src/CSS dizini oluşturun. Amacı, projenin . css dosyalarını depolamadır.

  9. Şu CSS ile src/CSS/Main. css oluşturun:

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

    Önceki Main. css dosyası uygulamayı stiller.

  10. Aşağıdaki JSON ile src/tsconfig.js oluşturun:

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

    Yukarıdaki kod, TypeScript derleyicisini ECMAScript 5 uyumlu JavaScript üretecek şekilde yapılandırır.

  11. Aşağıdaki kodla src/index. TS oluşturun:

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

    Önceki TypeScript, DOM öğelerine başvuruları alır ve iki olay işleyicisini ekler:

    • keyup: Bu olay Kullanıcı tbMessage metin kutusuna yazdığında ateşlenir. sendKullanıcı ENTER tuşuna bastığında işlev çağrılır.
    • click: Kullanıcı Gönder düğmesine tıkladığında bu olay ateşlenir. send işlevi çağrılır.

Uygulamayı yapılandırma

  1. İçinde Startup.Configure , usedefaultfiles ve usestaticfilesöğesine çağrılar ekleyin.

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

    Yukarıdaki kod, sunucunun index.html dosyasını bulmasını ve sunması için izin verir. Dosya, kullanıcının tam URL 'sini veya Web uygulamasının kök URL 'sini girip girmediğini görür.

  2. Sonunda Startup.Configure , bir /hub yolunu hub 'a eşleyin ChatHub . Merhaba Dünya görüntülenen kodu değiştirin ! aşağıdaki satırla birlikte:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapHub<ChatHub>("/hub");
    });
    
  3. içinde Startup.ConfigureServices Ekle'yi arayın. SignalR

    services.AddSignalR();
    
  4. Hub'ı depolamak için proje kökü SignalR WebPack/ içinde Hubs adlı yeni bir dizin SignalR oluşturun.

  5. Aşağıdaki kodla hub Hubs/ChatHub.cs oluşturun:

    using Microsoft.AspNetCore.SignalR;
    using System.Threading.Tasks;
    
    namespace SignalRWebPack.Hubs
    {
        public class ChatHub : Hub
        {
        }
    }
    
  6. Başvuru sorununu using çözmek için Startup.cs dosyasının en üstüne aşağıdaki deyimi ChatHub ekleyin:

    using SignalRWebPack.Hubs;
    

İstemci ve sunucu iletişimini etkinleştirme

Uygulama şu anda ileti göndermek için temel bir form görüntüler, ancak henüz işlevsel değildir. Sunucu belirli bir yolu dinliyor ama gönderilen iletilerle hiçbir şey yapmadı.

  1. Proje kökünde aşağıdaki komutu çalıştırın:

    npm i @microsoft/signalr @types/node
    

    Yukarıdaki komut şunları yüklemiş:

    • İstemcinin sunucuya ileti göndermesini sağlayan SignalR TypeScriptistemcisi.
    • Veri türleri için TypeScript Node.js tanımları. Bu türler için derleme zamanı Node.js sağlar.
  2. Vurgulanan kodu src/index.ts dosyasına ekleyin:

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

    Yukarıdaki kod, sunucudan ileti almayı destekler. sınıfı, HubConnectionBuilder sunucu bağlantısını yapılandırmak için yeni bir oluşturucu oluşturur. işlevi withUrl hub URL'sini yapılandırıyor.

    SignalR bir istemci ile sunucu arasında ileti alışverişinde bulunabilirsiniz. Her iletinin belirli bir adı var. Örneğin, adı olan messageReceived iletiler, ileti bölgesinde yeni iletiyi görüntülemekle sorumlu mantığı çalıştırabilirsiniz. Belirli bir iletiyi dinlemek işlevi aracılığıyla on yapılabilir. Herhangi bir sayıda ileti adı için takipte tutulabilirsiniz. Ayrıca iletiye yazarın adı ve alınan iletinin içeriği gibi parametreler de gönderebilirsiniz. İstemci bir ileti aldığında, yazarın adıyla ve özniteliğinde ileti içeriğiyle div yeni bir öğe innerHTML oluşturulur. İletileri görüntüleyen ana div öğeye eklenir.

  3. Artık istemci bir ileti alayana kadar, bunu ileti gönderecek şekilde yapılandırabilirsiniz. Vurgulanan kodu src/index.ts dosyasına ekleyin:

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

    WebSockets bağlantısı üzerinden ileti göndermek için yönteminin çağrılsı send gerekir. Yöntemin ilk parametresi ileti adıdır. İleti verileri diğer parametreleri içerir. Bu örnekte, olarak tanımlanan bir newMessage ileti sunucuya gönderilir. İleti, bir metin kutusundan kullanıcı adı ve kullanıcı girdilerinden oluşur. Gönderme işe yararsa metin kutusu değeri temiz olur.

  4. NewMessage yönetimini ChatHub sınıfına ekleyin:

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

    Yukarıdaki kod, alınan iletileri sunucu tarafından alındıktan sonra tüm bağlı kullanıcılara yayınlar. Tüm iletileri almak için genel bir on yönteme sahip olmak gereksizdir. İleti adından sonra adlı bir yöntem yeterlidir.

    Bu örnekte, TypeScript istemcisi olarak tanımlanan bir ileti newMessage gönderir. C# NewMessage yöntemi, istemci tarafından gönderilen verileri bekler. Clients.Allüzerinde SendAsync'e bir çağrı yapılır. Alınan iletiler hub'a bağlı tüm istemcilere gönderilir.

Uygulamayı test etme

Uygulamanın aşağıdaki adımlarla çalıştığını onaylayın.

  1. Webpack'i yayın modunda çalıştırın. Paket Yöneticisi Konsol penceresini kullanarak proje kökünde aşağıdaki komutu çalıştırın. Proje kökünde değilken komutunu cd SignalRWebPack girmeden önce girin.

    npm run release
    

    Bu komut, uygulamayı çalıştırarak hizmet için istemci tarafı varlıkları üretir. Varlıklar wwwroot klasörüne yerleştirilir.

    Webpack aşağıdaki görevleri tamamladı:

    • wwwroot dizininin içeriği temizildi.
    • Dönüştürme olarak bilinen bir işlemde TypeScript'i JavaScript'e dönüştürüldu.
    • Azaltma olarak bilinen bir işlemde dosya boyutunu azaltmak için oluşturulan JavaScript'i dolayın.
    • İşlenen JavaScript, CSS ve HTML dosyalarını src'den wwwroot dizinine kopyaladı.
    • wwwroot/index.html dosyasına aşağıdaki öğeleri girdi:
      • <link> wwwroot/main. adresine başvuran bir etiket. <hash> . css dosyası. Bu etiket, kapanış etiketinin hemen </head> öncesine yerleştirilir.
      • En <script> küçük wwwroot/main. adresine başvuran bir etiket. <hash> . js dosyası. Bu etiket, kapanış etiketinin hemen </body> öncesine yerleştirilir.
  2. Hata ayıklayıcıyı > eklemeden uygulamayı tarayıcıda başlatmak için Hata Ayıklama Olmadan Başlat'ı seçin. wwwroot/index.html dosyası adresinde http://localhost:<port_number> sunulmaktadır.

    Derleme hataları olursa çözümü kapatıp yeniden açmayı deneyin.

  3. Başka bir tarayıcı örneği (herhangi bir tarayıcı) açın. URL'yi adres çubuğuna yapıştırın.

  4. Tarayıcıdan birini seçin, İleti metin kutusuna bir şey yazın ve Gönder düğmesine tıklayın. Benzersiz kullanıcı adı ve iletisi her iki sayfada da anında görüntülenir.

her iki tarayıcı penceresinde de görüntülenen ileti

Önkoşullar

ASP.NET Core web uygulaması oluşturma

Path Visual Studio değişkensinde npm'yi araması için yapılandırmayı yapılandırma. Varsayılan olarak, Visual Studio yükleme dizininde bulunan npm sürümünü kullanır. Aşağıdaki yönergeleri izleyin Visual Studio:

  1. Araçlar Seçenekler Projeleri > ve Çözümleri Web > Uygulaması'Paket Yönetimi Dış Web > > Araçları'ne gidin.

  2. Listeden $(PATH) girişini seçin. Girişi listede ikinci konuma taşımak için yukarı oka tıklayın.

    Visual Studio Yapılandırma

Visual Studio yapılandırma tamamlandı. Artık projeyi oluşturabilirsiniz.

  1. Dosya Yeni Uygulama > > Project seçeneğini kullanın ve web uygulaması ASP.NET Core seçin.
  2. Projeye SignalR WebPack adını girin ve Oluştur'a seçin.
  3. Hedef çerçeve açılan listesinden .NET Core'ASP.NET Core 2.2'yi seçin. Boş şablonu seçin ve Oluştur'a seçin.

Webpack ve TypeScript'i yapılandırma

Aşağıdaki adımlarda TypeScript'in JavaScript'e dönüştürmesi ve istemci tarafı kaynaklarının gruplama işlemi yapılandırılır.

  1. Proje kökünde aşağıdaki komutu çalıştırarak dosyada package.jsoluşturun:

    npm init -y
    
  2. Vurgulanan özelliği dosyanın package.js ekleyin:

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

    özelliğini private olarak true ayarlama, sonraki adımda paket yükleme uyarılarını önler.

  3. Gerekli npm paketlerini yükleyin. Proje kökünden aşağıdaki komutu çalıştırın:

    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
    

    Aklınızda bazı komut ayrıntıları:

    • Sürüm numarası @ her paket adı için işareti izler. NPM bu özel paket sürümlerini yüklüyor.
    • Bu -E seçenek, NPM 'nin anlam sürümü oluşturma aralığı işleçlerini package.js için varsayılan davranışını devre dışı bırakır. Örneğin, "webpack": "4.29.3" yerine kullanılır "webpack": "^4.29.3" . Bu seçenek, daha yeni paket sürümlerine istenmeden yükseltme yapılmasını engeller.

    Daha fazla ayrıntı için bkz. NPM-Install docs.

  4. scriptsDosyadaki package.js özelliğini aşağıdaki kodla değiştirin:

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

    Betiklerin bazı açıklamaları:

    • build: İstemci tarafı kaynaklarını geliştirme modunda paketler ve dosya değişikliklerini izler. Dosya izleyici, bir proje dosyası her değiştiğinde paketin yeniden oluşturulmasına neden olur. modeSeçeneği, Tree gerçekleşmesi ve minbirleşme gibi üretim iyileştirmeleri devre dışı bırakır. Yalnızca build geliştirme aşamasında kullanın.
    • release: İstemci tarafı kaynaklarını üretim modunda paketlayın.
    • publish: release İstemci tarafı kaynaklarını üretim modunda paketleyip betiği çalıştırır. Uygulamayı yayımlamak için .NET Core CLI Publish komutunu çağırır.
  5. Proje kökünde aşağıdaki kodla webpack.config.js adlı bir dosya oluşturun:

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

    Yukarıdaki dosya Web paketi derlemesini yapılandırır. Aklınızda bazı yapılandırma ayrıntıları:

    • outputÖzelliği, dağ'ın varsayılan değerini geçersiz kılar. Paket, Wwwroot dizininde yayınlanır.
    • resolve.extensionsDizi, Istemci JavaScript 'i içeri aktarmak için .js içerir SignalR .
  6. Projenin istemci tarafı varlıklarını depolamak için proje kökünde yeni bir src dizini oluşturun.

  7. Aşağıdaki işaretle src/index.html oluşturun.

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

    Önceki HTML, giriş sayfasının ortak işaretlemesini tanımlar.

  8. Yeni bir src/CSS dizini oluşturun. Amacı, projenin . css dosyalarını depolamadır.

  9. Şu biçimlendirmeye sahip src/CSS/Main. css oluşturun:

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

    Önceki Main. css dosyası uygulamayı stiller.

  10. Aşağıdaki JSON ile src/tsconfig.js oluşturun:

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

    Yukarıdaki kod, TypeScript derleyicisini ECMAScript 5 uyumlu JavaScript üretecek şekilde yapılandırır.

  11. Aşağıdaki kodla src/index. TS oluşturun:

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

    Önceki TypeScript, DOM öğelerine başvuruları alır ve iki olay işleyicisini ekler:

    • keyup: Bu olay Kullanıcı tbMessage metin kutusuna yazdığında ateşlenir. sendKullanıcı ENTER tuşuna bastığında işlev çağrılır.
    • click: Kullanıcı Gönder düğmesine tıkladığında bu olay ateşlenir. send işlevi çağrılır.

ASP.NET Core uygulamasını yapılandırma

  1. Yönteminde belirtilen kod Startup.Configure Merhaba Dünya! görüntülüyor. app.RunYöntem çağrısını usedefaultfiles ve usestaticfilesçağrılarıyla değiştirin.

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

    Yukarıdaki kod, kullanıcının tam URL 'sini veya Web uygulamasının kök URL 'sini girip girmediğini index.html dosyasını bulmasını ve sunmasını sağlar.

  2. Add SignalR eklentisini çağırın Startup.ConfigureServices . SignalRHizmetleri projeye ekler.

    services.AddSignalR();
    
  3. Bir /hub yolunu hub 'a eşleyin ChatHub . Aşağıdaki satırları sonuna ekleyin Startup.Configure :

    app.UseSignalR(options =>
    {
        options.MapHub<ChatHub>("/hub");
    });
    
  4. Proje kökünde hub olarak adlandırılan yeni bir dizin oluşturun. Amacı, bir SignalR sonraki adımda oluşturulan hub 'ı deposağlamaktır.

  5. Aşağıdaki kodla hub hub 'ları/ChatHub. cs oluşturun:

    using Microsoft.AspNetCore.SignalR;
    using System.Threading.Tasks;
    
    namespace SignalRWebPack.Hubs
    {
        public class ChatHub : Hub
        {
        }
    }
    
  6. Başvuruyu çözümlemek için Startup. cs dosyasının en üstüne aşağıdaki kodu ekleyin ChatHub :

    using SignalRWebPack.Hubs;
    

İstemci ve sunucu iletişimini etkinleştir

Uygulama Şu anda ileti göndermek için basit bir form görüntülüyor. Bunu yapmayı denediğinizde hiçbir şey olmaz. Sunucu belirli bir yolu dinliyor, ancak gönderilen iletilerle hiçbir şey yapmıyor.

  1. Proje kökünde aşağıdaki komutu çalıştırın:

    npm install @aspnet/signalr
    

    Yukarıdaki komut, istemcinin sunucuya ileti göndermesini sağlayan SignalR TypeScript istemcisiniyüklüyor.

  2. Vurgulanan kodu src/index. TS dosyasına ekleyin:

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

    Yukarıdaki kod, sunucudan ileti almayı destekler. HubConnectionBuilderSınıfı, sunucu bağlantısını yapılandırmak için yeni bir Oluşturucu oluşturur. withUrlİşlevi hub URL 'sini yapılandırır.

    SignalR istemci ve sunucu arasında ileti alışverişi yapılmasını mümkün. Her ileti belirli bir ada sahiptir. Örneğin, adı olan mesajlar ileti messageReceived bölgesindeki yeni iletiyi görüntülemeden sorumlu mantığı çalıştırabilir. Belirli bir iletiyi dinlemek, işlevi aracılığıyla yapılabilir on . Herhangi bir sayıda ileti adını dinleyebilmeniz gerekir. Ayrıca, yazarın adı ve alınan iletinin içeriği gibi parametreleri iletiye geçirmek da mümkündür. İstemci bir ileti aldıktan sonra div yazarın adı ve onun özniteliğinde ileti içeriğiyle yeni bir öğe oluşturulur innerHTML . Yeni ileti, div iletileri görüntüleyen Main öğesine eklenir.

  3. Artık istemci bir ileti aldığına göre, ileti gönderecek şekilde yapılandırın. Vurgulanan kodu src/index. TS dosyasına ekleyin:

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

    WebSockets bağlantısı aracılığıyla bir ileti gönderildiğinde yönteminin çağrılması gerekir send . Yöntemin ilk parametresi ileti adıdır. İleti verileri diğer parametreleri geçersiz kılar. Bu örnekte, sunucusuna gönderildiği şekilde tanımlanan bir ileti newMessage . İleti, bir metin kutusundan Kullanıcı adından ve Kullanıcı girişinden oluşur. Gönderme işlemi çalışırsa metin kutusu değeri temizlenir.

  4. NewMessage yönetimini ChatHub sınıfına ekleyin:

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

    Yukarıdaki kod, sunucu onları aldıktan sonra tüm bağlı kullanıcılara ileti almış iletileri yayınlar. onTüm iletileri almak için genel bir yöntem olması gereksizdir. İleti adından sonra adlandırılmış bir yöntem.

    Bu örnekte, TypeScript istemcisi olarak tanımlanan bir ileti gönderir newMessage . C# NewMessage yöntemi, istemci tarafından gönderilen verileri bekliyor. Istemcilerde Sendadsync çağrısı yapılır . tümü. Alınan iletiler, hub 'a bağlı tüm istemcilere gönderilir.

Uygulamayı test etme

Uygulamanın aşağıdaki adımlarla çalıştığından emin olun.

  1. Web paketini yayın modunda çalıştırın. Paket Yöneticisi konsolu penceresini kullanarak, proje kökünde aşağıdaki komutu çalıştırın. Proje kökünde değilseniz, cd SignalRWebPack komutu girmeden önce girin.

    npm run release
    

    Bu komut, uygulamayı çalıştırarak hizmet için istemci tarafı varlıkları üretir. Varlıklar wwwroot klasörüne yerleştirilir.

    Webpack aşağıdaki görevleri tamamladı:

    • wwwroot dizininin içeriği temizildi.
    • Dönüştürme olarak bilinen bir işlemde TypeScript'i JavaScript'e dönüştürüldu.
    • Azaltma olarak bilinen bir işlemde dosya boyutunu azaltmak için oluşturulan JavaScript'i dolayın.
    • İşlenen JavaScript, CSS ve HTML dosyalarını src'den wwwroot dizinine kopyaladı.
    • wwwroot/index.html dosyasına aşağıdaki öğeleri girdi:
      • <link> wwwroot/main. adresine başvuran bir etiket. <hash> . css dosyası. Bu etiket, kapanış etiketinin hemen </head> öncesine yerleştirilir.
      • En <script> küçük wwwroot/main. adresine başvuran bir etiket. <hash> . js dosyası. Bu etiket, kapanış etiketinin hemen </body> öncesine yerleştirilir.
  2. Hata > ayıklayıcıyı eklemeden uygulamayı tarayıcıda başlatmak için hata ayıklama olmadan Başlat ' ı seçin. Wwwroot/index.html dosyası ' de sunulur http://localhost:<port_number> .

  3. Başka bir tarayıcı örneği (herhangi bir tarayıcı) açın. URL 'YI adres çubuğuna yapıştırın.

  4. Tarayıcı seçin, ileti metin kutusuna bir şey yazın ve Gönder düğmesine tıklayın. Benzersiz Kullanıcı adı ve ileti anında her iki sayfada da görüntülenir.

ileti hem tarayıcı penceresinde görüntüleniyor

Ek kaynaklar