遊び場:ASP.ネット5 signalr


ああ!
エステポストは、アーマAtualizaは、アーティゴーをします、そして、e nele falaremos sobre o que mudoue e o que foi acrescentado ao signalrは、Ver .NET 5 .カノnスルo o tenhaリドo artigo前方、recomendo que o faは、e baixe seu c - dio forte、pois partiremos dele para o fafas neste artigo.
vamos l .

オルタナートAは、projetoをします


アンデスデMais Nada、Precisamos atualizar nosso projeto para o asp .NET 5 .e、パラソル、vamos ao arquivoPlayground.SignalR.Stocks.csproj E Dixアロー- lo como segue :
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.3" />
  </ItemGroup>

</Project>
Aqui Temos 3 Mudanは、以下として扱います:1つのAtualizaは、oを得ます.経由タグTargetFramework , コム・モニカnet5.0 ; 2 ) Habilita属Nullable Reference Types C・・・・・・3 ) Serializa de Serialteca de a Orioiza - a - a da a MessagePack , Qe Explicaremos A Seguir

Atualizaは、oメッセーパックをします。X


パラAは5.0を行う.ネットコア、依存しているNCIA da BilotetecaはMessagePack foi atualizadaをします.M .グロスゾ・モード・エッセ・モーダン: A・A・A・A・モーゼーヌ・デ・メヌサンス著『E・トラーマ』における「形容詞」
パラシュートで降下する人エサMudanは、e comoエラRecord Types アルカイボ・シャドードのC . ChornQuoteDtos.cs パスタModels <論説>プロジェトとE .
using MessagePack;
using System;

namespace Playground.SignalR.Stocks.Models
{
    [MessagePackObject(true)]
    public record QuoteRequest(string CurrentSymbol, string NewSymbol);

    [MessagePackObject(true)]
    public record QuoteResponse(string Symbol, decimal Price, DateTime Time);
}
Repare que、Ao controは、リオのDer - Verが、元のproproto、temosMessagePackObject , <研究ノート>フォア・アノバットにおけるフォーマの役割Serializable Jは、presenteなしcチェン、e indica que um dado tipo pode ser serializado pelo messagepackです.Oワルtrue 所有者を抑制するkeyAsPropertyName , QUE INFORMANA AO MessagePack qual Modelo de Serializa Peristro o ser

Nota: Existem dois modelos de serialização no MessagePack: indexado e por propriedade. De forma simples, o indexado cria um array onde cada propriedade de nossos tipos estará presente em um índice, e o por propriedade cria um objeto complexo onde cada propriedade é referida as is. O modelo indexado cria um objeto menor e, por isso, é mais performático. Mas, para evitarmos mudanças no consumo das mensagens em nosso cliente JS, optamos por usar o modelo por propriedades.


アゴラTemos Dois dtos、um que Representaは、ルネッサンスo o oである.Mis - Are Frente Veremos como Ambos s

Atualizaは、oをしますo o o o o o o o o o o o o o


UMA Segunda Mudan - Renacionada Ao Messagepack - a forma como o mesmoについてネットコアIList<MessagePack.IFormatterResolver> ), Pia um Tipo da PR An Pria Biblioteca do MessagePack , OMessagePackSerializationOptions .
nは、利用可能なエステは、コンティニュラの元のPorque assummosとして設定します.
パラRealizarmosエステConfiguraは、Sexo o o、Vamos Ao ArquivoStartup.cs ファーザー・ウマ・オルタナの『アウダ』
.AddMessagePackProtocol();
Pasaremos - To o seguinte :
.AddMessagePackProtocol(options =>
                        options.SerializerOptions = MessagePackSerializerOptions.Standard
                                                                                .WithSecurity(MessagePackSecurity.UntrustedData)
                    );
Muito重要な点:Menito EngineとしてのエサインディアナAO MessagePack que Mensagens que serは、recesidasパラシュートで降下します.エステは、maのコンフィギュレーション<翻訳>スペイン語を中心としてMessagePackSecurity.TrustedData Menhorar O Desempenho da Troca de MensagensにおけるPode serの利用
アゴラque temum um dto para enviar cotaの祖先o o ao cliente,vamos fazer uma pquena altera pose o em nosso modelo de dose no nnio,cota poiso o que que atualizada em nosso servi se o para ser ser viviada ao clienteパラアイソ、ヴァーモスアオArquivoQuote.cs , アイダナパスタModels , E vamos異形のo conteは、パラオo seguinteをします
using System;

namespace Playground.SignalR.Stocks.Models
{
    public class Quote
    {
        public string Symbol { get; }
        public decimal Price { get; private set; }
        public DateTime Time { get; private set; }

        private Quote(string symbol) =>
            Symbol = symbol;

        public static Quote Create(string symbol) =>
            new Quote(symbol);

        public void Update(decimal price)
        {
            Price = price;
            Time = DateTime.Now;
        }
    }
}
<論文>アクィ・ム・ヌ・ニマのムダン・モー--「ヴァルドール・デヴィッド」における民俗学の内在Symbol デNosso工場方法、E issoポルケNullable Reference Types エムnosso projeto、o que passou exigir queのシンボル、nnullable , sempre vitesse valor apはsの構文を示します.nはo foo por causa deste tipo que habilamos a機能,mas sim por causa de outro que explicaremos a seguir

ハブフィルタ


Estaは、UMA Novidade Dista Verがo o o oをsignalrにします.デForma Semelhante AOSフィルタは、ASPをします.NETコアは、OSのハブのフィルタsは、oのexecutadosエムduas ocasie quando um m todo doハブは、インボカドです.
Per Conhecermos um Pouco Melhor Esta特徴,Vamos Criar Dois FiltrosパラIsoso、VamosクリアーパスタFilters ナ・ラ・レズ『プロジェト・E』『セグナ』『批評家』ConnectionFilter.cs COM o seguinteコンテ
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;

namespace Playground.SignalR.Stocks.Filters
{
    public class ConnectionFilter : IHubFilter
    {
        public Task OnConnectedAsync(HubLifetimeContext context,
                                     Func<HubLifetimeContext, Task> next)
        {
            Console.WriteLine($"New client connected. Connection ID: {context.Context.ConnectionId}");

            return next(context);
        }

        public Task OnDisconnectedAsync(HubLifetimeContext context,
                                        Exception? exc,
                                        Func<HubLifetimeContext, Exception?, Task> next)
        {
            Console.WriteLine($"Client with connection ID {context.Context.ConnectionId} has disconnected.");
            if (exc != null)
                Console.WriteLine($"Disconnection exception: {exc}");

            return next(context, exc);
        }
    }
}
インテンシブは、o deste filtroを登録します.Prip - isso , Outzzamos os m to dosOnConnectedAsyncOnDisconnectedAsync インターフェイスIHubFilter . ラピスque na assinaturaはmをするOnDisconnectedAsync 天王寺例外nullable . Porコンタは、USOデをしますNullable Reference Types インターフェイスIHubFilter アピタマス・ピタ・ハビタラー・オ・リヌス( Huitilamos diretamente no projeto por simplicidade )
アゴラ、Vamos Criar O Segundo Filtro、que serQuoteHub Aciionadoのために、E Gerarは、記憶装置を使いますConnectionId パラobtaコタエスシス.パラアイソ、Vamosクリアーo ArquivoQuoteHubFilter.cs , タマムパスタFilters セグンテ・コンテ
using Microsoft.AspNetCore.SignalR;
using Playground.SignalR.Stocks.Models;
using System;
using System.Threading.Tasks;

namespace Playground.SignalR.Stocks.Filters
{
    public class QuoteHubFilter : IHubFilter
    {
        public async ValueTask<object?> InvokeMethodAsync(HubInvocationContext invocationContext,
                                                          Func<HubInvocationContext,
                                                          ValueTask<object?>> next)
        {
            var request = invocationContext.HubMethodArguments[0] as QuoteRequest;

            try
            {
                if(request != null)
                    Console.WriteLine($"{invocationContext.Context.ConnectionId} has selected {request.NewSymbol}.");

                return await next(invocationContext);
            }
            catch (Exception exc)
            {
                if(request != null)
                    Console.WriteLine($"Error switching symbol to '{request.NewSymbol}': {exc}");

                throw;
            }
        }
    }
}
アクシーカベum detalhe interessanteinvocationContext <研究ノート>類型としての詩文HttpContext いいえASP.ネットアルマの所有者HubMethodName , エーモス・K・O・フィトロ・エクスタットドの『トーマス・ゴスター』についてエムnossoカソ、comoQuoteHub <研究ノート>第二次世界大戦後の日本語教育に関する一考察QuoteRequest ).

Nota: ambos os filtros implementam IHubFilter, mas implementam métodos diferentes. No primeiro filtro temos OnConnectedAsync e OnDisconnectedAsync. Já no segundo, temos InvokeMethodAsync apenas. Isso acontece porque a interface IHubFilter se utiliza da feature Default Interface Implementation, do C# 8. Ou seja, na ausência de uma implementação para um de seus métodos, a própria interface provê um comportamento padrão. Podemos falar sobre esta feature em artigo futuro.


コンフィギュレーション


アゴラtemdeデinformar ao asp .ネットcomo nossos filtros devem funcionarドスティポデFiltro : globais e locais.OS globais s o o aqueles executados em todos os hubs,e os locais s emero o executadosハブハブフィニフィドCOCO queremos saber quando um cliente se conecta a partimはPrimeiro Filtro,Vamos Configurore,lo como globalを行う.パラアイソ、ヴァーモスアオArquivoStartup.cs e alterar o registroはsignalrをします.オンデt Nannos
.AddSignalR()
パスサレッツ
.AddSignalR(options =>
            options.AddFilter<ConnectionFilter>()
            )
Jは、nosso FiltroデコタStrakes es es ser地方、Ma Vaz que sua execuの残りのo o o est estの制限を支配します.ヴァモス,アイダノアーキヴォボStartup.cs , Incluir o seguinte conteは、ロゴをabaixoします.
.AddHubOptions<QuoteHub>(options =>
                            options.AddFilter<QuoteHubFilter>()
                        )
com isso temos nossos filtros ConfigadosパラInternetter Tanto OS Eventos de conex is o o/desconexは、O、Quanto Ao - Pedido de cota

アジュスストフィナーレ


アゴラEstamos PRは、Ximos Daを結論します‖o a a a a aplicaは、apisas、Informar ao Sistema que nosos dtosデcotaQuoteRequestQuoteRespose ) SERの利用パラISSO、VAMASファーザーduas mudanは、.
PrimeiraなしArquivoIQuoteHub.cs パスタHubs , ヴァーモ・オルタナール・コンテ
using System.Threading.Tasks;
using Playground.SignalR.Stocks.Models;

namespace Playground.SignalR.Stocks.Hubs
{
    public interface IQuoteHub
    {
        Task SendQuote(QuoteResponse quote);
    }
}
EM SEGINA、VAMASの異形のnossoバックグラウンドサービスのInvoocaエステmはtodo de nossoハブ.パラアイソ、ヴァーモスアオArquivoQuoteWorker パスタWorkers , E fafaerは、seguinteの代用品です
await _hub.Clients.Group(quote.Symbol).SendQuote(quote);
パスサレッツ
await _hub.Clients.Group(quote.Symbol).SendQuote(new QuoteResponse(quote.Symbol, quote.Price, quote.Time));
MegsagensデTrensi地方としてのアゴラ、Vamos Mudar NossoハブパラシュートQuoteHub.cs , パスタHubs , Vamos atualizar seu conte - to pelo seguinte :
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Playground.SignalR.Stocks.Models;

namespace Playground.SignalR.Stocks.Hubs
{
    public class QuoteHub : Hub<IQuoteHub>
    {
        public async Task ChangeSubscription(QuoteRequest request)
        {
            if(!string.IsNullOrEmpty(request.CurrentSymbol))
                await Groups.RemoveFromGroupAsync(Context.ConnectionId, request.CurrentSymbol);

            await Groups.AddToGroupAsync(Context.ConnectionId, request.NewSymbol);        
        }
    }
}
E、Por fim、vamos atualizar nosso clienteは、JavaScriptをパラパラにします.いいえArquivoquotes.js パスタwwwroot\js , オンデt Nannos
quoteConn.invoke("ChangeSubscription", currentSymbol, event.target.value)
パスサレッツ
quoteConn.invoke("ChangeSubscription", { CurrentSymbol: currentSymbol, NewSymbol: event.target.value })

E voi l '!


com isso、temos nossa aplicaは、発音を発音します.テュド・デ・セルテ,デレモス・ター・セーテの試み,エレチェーンヘン"ITUB 4 "

E o seguinteなしコンソール、AP通信s fechar o navegador:

結論


Realizadasなしsignalrパラオo aspとしてのMudanのように.NET 5 5 Truxeramのmais desempenho para troca de mensagens,e maor flexbilidade com a include s o o dos filtrsアパルトメンツ単体としてのS・O・ムダン・パープ、マス・ク・クリムは、パラスのパラオの主題であるスー・アパルカ・・・・.レチュラ・Adocumentação do MessagePack 2 < em - Lings - s >パラmaiores detalhes , pois al ' m de haver diversus op de Confiilaの結果正午の正午
コスモデコスチュームrepositório do Github C o o c dio deste artigo
ゴット?Me deixeサーベルpelos indicadores.TEM‐AlGauma d’VIDAか?社会におけるコンテナー・ペナスの受容
で、私はprを言います!