Použití protokolu Centra MessagePack pro SignalR ASP.NET Core
Tento článek předpokládá, že čtenář je obeznámen s tématy popsanými v tématu Začínáme s ASP.NET Core SignalR.
Co je MessagePack?
MessagePack je rychlý a kompaktní binární serializační formát. Je užitečné, když se jedná o výkon a šířku pásma, protože vytváří menší zprávy než JSON. Binární zprávy jsou při pohledu na trasování sítě a protokoly nečitelné, pokud nejsou bajty předány prostřednictvím analyzátoru MessagePack. SignalR má integrovanou podporu pro formát MessagePack a poskytuje rozhraní API pro použití klienta a serveru.
Konfigurace balíčku MessagePack na serveru
Pokud chcete na serveru povolit protokol MessagePack Hub, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček do aplikace. Startup.ConfigureServices
V metodě přidejte AddMessagePackProtocol
do AddSignalR
volání povolení podpory MessagePack na serveru.
services.AddSignalR()
.AddMessagePackProtocol();
Poznámka:
Json je ve výchozím nastavení povolený. Přidání MessagePacku umožňuje podporu pro klienty JSON i MessagePack.
Pokud chcete přizpůsobit, jak MessagePack formátuje data, AddMessagePackProtocol
přebírá delegáta pro konfiguraci možností. V daném delegátu se SerializerOptions
vlastnost používá ke konfiguraci možností serializace MessagePack. Další informace o tom, jak překladače fungují, naleznete v knihovně MessagePack na MessagePack-CSharp. Atributy lze použít u objektů, které chcete serializovat, a definovat, jak mají být zpracovány.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(new CustomResolver())
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Upozorňující
Důrazně doporučujeme zkontrolovat CVE-2020-5234 a použít doporučené opravy. Například volání .WithSecurity(MessagePackSecurity.UntrustedData)
při nahrazení .SerializerOptions
Konfigurace balíčku MessagePack v klientovi
Poznámka:
Pro podporované klienty je ve výchozím nastavení povolený JSON. Klienti můžou podporovat pouze jeden protokol. Přidání podpory MessagePacku nahrazuje všechny dříve nakonfigurované protokoly.
Klient .NET
Chcete-li povolit MessagePack v klientovi .NET, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček a volání AddMessagePackProtocol
.HubConnectionBuilder
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Poznámka:
Toto AddMessagePackProtocol
volání přebírá delegáta pro konfiguraci možností stejně jako server.
Javascriptový klient
Podpora MessagePacku pro klienta JavaScriptu je poskytována balíčkem npm @microsoft/signalr-protocol-msgpack npm. Nainstalujte balíček spuštěním následujícího příkazu v příkazovém prostředí:
npm install @microsoft/signalr-protocol-msgpack
Po instalaci balíčku npm je možné modul použít přímo přes zavaděč modulu JavaScript nebo importovat do prohlížeče odkazováním na následující soubor:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Následující požadované soubory javaScriptu musí být odkazovány v uvedeném pořadí:
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
Přidání .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
do HubConnectionBuilder
konfigurace klienta pro použití protokolu MessagePack při připojování k serveru.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
V tuto chvíli neexistují žádné možnosti konfigurace protokolu MessagePack v javascriptovém klientovi.
Java klient
Pokud chcete povolit MessagePack s Javou com.microsoft.signalr.messagepack
, nainstalujte balíček. Pokud používáte Gradle, přidejte do dependencies
oddílu souboru build.gradle následující řádek:
implementation 'com.microsoft.signalr.messagepack:signalr-messagepack:5.0.0'
Při použití Mavenu přidejte do elementu pom.xml
souboru následující řádky<dependencies>
:
<dependency>
<groupId>com.microsoft.signalr.messagepack</groupId>
<artifactId>signalr</artifactId>
<version>5.0.0</version>
</dependency>
Zavolejte withHubProtocol(new MessagePackHubProtocol())
.HubConnectionBuilder
HubConnection messagePackConnection = HubConnectionBuilder.create("YOUR HUB URL HERE")
.withHubProtocol(new MessagePackHubProtocol())
.build();
Důležité informace o balíčku MessagePack
Při použití protokolu MessagePack Hub je potřeba mít na paměti několik problémů.
MessagePack rozlišují malá a velká písmena.
V protokolu MessagePack se rozlišují malá a velká písmena. Představte si například následující třídu jazyka C#:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Při odesílání z klienta JavaScriptu musíte použít PascalCased
názvy vlastností, protože velikost písmen musí přesně odpovídat třídě jazyka C#. Příklad:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Použití camelCased
názvů nebude správně svázané s třídou jazyka C#. Tento problém můžete obejít pomocí atributu Key
, který určuje jiný název vlastnosti MessagePack. Další informace najdete v dokumentaci MessagePack-CSharp.
DateTime.Kind se nezachová při serializaci/deserializaci
Protokol MessagePack neposkytuje způsob kódování Kind
hodnoty DateTime
. V důsledku toho se při deserializaci data protokol Centra MessagePack převede na formát UTC, pokud DateTime.Kind
je DateTimeKind.Local
jinak nedotkne času a předá ho tak, jak je. Pokud pracujete s DateTime
hodnotami, doporučujeme před jejich odesláním převést na UTC. Převeďte je z UTC na místní čas, když je obdržíte.
Podpora MessagePacku v prostředí kompilace s předstihem
Knihovna MessagePack-CSharp používaná klientem a serverem .NET používá generování kódu k optimalizaci serializace. V důsledku toho se ve výchozím nastavení nepodporuje v prostředích, která používají kompilaci s předstihem (například Xamarin iOS nebo Unity). MessagePack je možné v těchto prostředích použít "předgenerováním" serializátoru/deserializátoru. Další informace najdete v dokumentaci MessagePack-CSharp. Jakmile serializátory předem vygenerujete, můžete je zaregistrovat pomocí delegáta konfigurace předaného do AddMessagePackProtocol
:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
StaticCompositeResolver.Instance.Register(
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
);
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(StaticCompositeResolver.Instance)
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Kontroly typů jsou v balíčku MessagePack přísnější.
Protokol CENTRA JSON provede převody typů během deserializace. Pokud například příchozí objekt má hodnotu vlastnosti, která je číslo ({ foo: 42 }
), ale vlastnost třídy .NET je typu string
, hodnota bude převedena. MessagePack však tento převod neprovádí a vyvolá výjimku, která se dá zobrazit v protokolech na straně serveru (a v konzole):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2937.
Znaky a řetězce v Javě
V klientovi char
Java budou objekty serializovány jako objekty s jedním znakem String
. To je na rozdíl od klienta C# a JavaScriptu, který je serializuje jako short
objekty. Samotná specifikace MessagePack nedefinuje chování pro char
objekty, takže je na autor knihovny, aby určil, jak je serializovat. Rozdíl v chování mezi našimi klienty je výsledkem knihoven, které jsme použili pro naše implementace.
Další materiály
Tento článek předpokládá, že čtenář je obeznámen s tématy popsanými v tématu Začínáme s ASP.NET Core SignalR.
Co je MessagePack?
MessagePack je rychlý a kompaktní binární serializační formát. Je užitečné, když je výkon a šířka pásma problém, protože ve srovnání s JSON vytváří menší zprávy. Binární zprávy jsou při pohledu na trasování sítě a protokoly nečitelné, pokud nejsou bajty předány prostřednictvím analyzátoru MessagePack. SignalR má integrovanou podporu pro formát MessagePack a poskytuje rozhraní API pro použití klienta a serveru.
Konfigurace balíčku MessagePack na serveru
Pokud chcete na serveru povolit protokol MessagePack Hub, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček do aplikace. Startup.ConfigureServices
V metodě přidejte AddMessagePackProtocol
do AddSignalR
volání povolení podpory MessagePack na serveru.
Poznámka:
Json je ve výchozím nastavení povolený. Přidání MessagePacku umožňuje podporu pro klienty JSON i MessagePack.
services.AddSignalR()
.AddMessagePackProtocol();
Pokud chcete přizpůsobit, jak bude MessagePack formátovat vaše data, AddMessagePackProtocol
vezme delegáta pro konfiguraci možností. V daném delegátu SerializerOptions
lze vlastnost použít ke konfiguraci možností serializace MessagePack. Další informace o tom, jak překladače fungují, naleznete v knihovně MessagePack na MessagePack-CSharp. Atributy lze použít u objektů, které chcete serializovat, a definovat, jak mají být zpracovány.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(new CustomResolver())
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Upozorňující
Důrazně doporučujeme zkontrolovat CVE-2020-5234 a použít doporučené opravy. Například volání .WithSecurity(MessagePackSecurity.UntrustedData)
při nahrazení .SerializerOptions
Konfigurace balíčku MessagePack v klientovi
Poznámka:
Pro podporované klienty je ve výchozím nastavení povolený JSON. Klienti můžou podporovat pouze jeden protokol. Přidání podpory MessagePacku nahradí všechny dříve nakonfigurované protokoly.
Klient .NET
Chcete-li povolit MessagePack v klientovi .NET, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček a volání AddMessagePackProtocol
.HubConnectionBuilder
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Poznámka:
Toto AddMessagePackProtocol
volání přebírá delegáta pro konfiguraci možností stejně jako server.
Javascriptový klient
Podpora MessagePacku pro klienta JavaScriptu je poskytována balíčkem npm @microsoft/signalr-protocol-msgpack npm. Nainstalujte balíček spuštěním následujícího příkazu v příkazovém prostředí:
npm install @microsoft/signalr-protocol-msgpack
Po instalaci balíčku npm je možné modul použít přímo přes zavaděč modulu JavaScript nebo importovat do prohlížeče odkazováním na následující soubor:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
V prohlížeči se na knihovnu msgpack5
musí odkazovat také. <script>
K vytvoření odkazu použijte značku. Knihovnu najdete na adrese node_modules\msgpack5\dist\msgpack5.js.
Poznámka:
Při použití elementu <script>
je pořadí důležité. Pokud signalr-protocol-msgpack.js
se odkazuje dříve msgpack5.js
, při pokusu o připojení pomocí MessagePacku dojde k chybě. signalr.js
je rovněž vyžadována před signalr-protocol-msgpack.js
.
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/msgpack5/msgpack5.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
Přidání .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
do HubConnectionBuilder
konfigurace klienta pro použití protokolu MessagePack při připojování k serveru.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Poznámka:
V tuto chvíli neexistují žádné možnosti konfigurace protokolu MessagePack v javascriptovém klientovi.
Java klient
Pokud chcete povolit MessagePack s Javou com.microsoft.signalr.messagepack
, nainstalujte balíček. Pokud používáte Gradle, přidejte do dependencies
oddílu souboru build.gradle následující řádek:
implementation 'com.microsoft.signalr.messagepack:signalr-messagepack:5.0.0'
Při použití Mavenu přidejte do elementu pom.xml
souboru následující řádky<dependencies>
:
<dependency>
<groupId>com.microsoft.signalr.messagepack</groupId>
<artifactId>signalr</artifactId>
<version>5.0.0</version>
</dependency>
Zavolejte withHubProtocol(new MessagePackHubProtocol())
.HubConnectionBuilder
HubConnection messagePackConnection = HubConnectionBuilder.create("YOUR HUB URL HERE")
.withHubProtocol(new MessagePackHubProtocol())
.build();
Důležité informace o balíčku MessagePack
Při použití protokolu MessagePack Hub je potřeba mít na paměti několik problémů.
MessagePack rozlišují malá a velká písmena.
V protokolu MessagePack se rozlišují malá a velká písmena. Představte si například následující třídu jazyka C#:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Při odesílání z klienta JavaScriptu musíte použít PascalCased
názvy vlastností, protože velikost písmen musí přesně odpovídat třídě jazyka C#. Příklad:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Použití camelCased
názvů nebude správně svázané s třídou jazyka C#. Tento problém můžete obejít pomocí atributu Key
, který určuje jiný název vlastnosti MessagePack. Další informace najdete v dokumentaci MessagePack-CSharp.
DateTime.Kind se nezachová při serializaci/deserializaci
Protokol MessagePack neposkytuje způsob kódování Kind
hodnoty DateTime
. V důsledku toho se při deserializaci data protokol Centra MessagePack převede na formát UTC, pokud DateTime.Kind
je DateTimeKind.Local
jinak nedotkne času a předá ho tak, jak je. Pokud pracujete s DateTime
hodnotami, doporučujeme před jejich odesláním převést na UTC. Převeďte je z UTC na místní čas, když je obdržíte.
MessagePack v JavaScriptu nepodporuje DateTime.MinValue
Knihovna msgpack5 používaná klientem SignalR JavaScriptu nepodporuje timestamp96
typ v MessagePacku. Tento typ se používá ke kódování velmi velkých hodnot kalendářních dat (buď velmi brzy v minulosti, nebo velmi daleko v budoucnu). Hodnota DateTime.MinValue
je January 1, 0001
, která musí být kódována v hodnotě timestamp96
. Z tohoto důvodu se odesílání DateTime.MinValue
do javascriptového klienta nepodporuje. Při DateTime.MinValue
přijetí javascriptovým klientem se vyvolá následující chyba:
Uncaught Error: unable to find ext type 255 at decoder.js:427
DateTime.MinValue
Obvykle se používá ke kódování "chybějící" nebo null
hodnoty. Pokud potřebujete tuto hodnotu zakódovat v balíčku MessagePack, použijte hodnotu nullable DateTime
(DateTime?
) nebo zakódujte samostatnou bool
hodnotu označující, jestli je datum k dispozici.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2228.
Podpora MessagePacku v prostředí kompilace s předstihem
Knihovna MessagePack-CSharp používaná klientem a serverem .NET používá generování kódu k optimalizaci serializace. V důsledku toho se ve výchozím nastavení nepodporuje v prostředích, která používají kompilaci s předstihem (například Xamarin iOS nebo Unity). MessagePack je možné v těchto prostředích použít "předgenerováním" serializátoru/deserializátoru. Další informace najdete v dokumentaci MessagePack-CSharp. Jakmile serializátory předem vygenerujete, můžete je zaregistrovat pomocí delegáta konfigurace předaného do AddMessagePackProtocol
:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
StaticCompositeResolver.Instance.Register(
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
);
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(StaticCompositeResolver.Instance)
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Kontroly typů jsou v balíčku MessagePack přísnější.
Protokol CENTRA JSON provede převody typů během deserializace. Pokud například příchozí objekt má hodnotu vlastnosti, která je číslo ({ foo: 42 }
), ale vlastnost třídy .NET je typu string
, hodnota bude převedena. MessagePack však tento převod neprovádí a vyvolá výjimku, která se dá zobrazit v protokolech na straně serveru (a v konzole):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2937.
Znaky a řetězce v Javě
V klientovi char
Java budou objekty serializovány jako objekty s jedním znakem String
. To je na rozdíl od klienta C# a JavaScriptu, který je serializuje jako short
objekty. Samotná specifikace MessagePack nedefinuje chování pro char
objekty, takže je na autor knihovny, aby určil, jak je serializovat. Rozdíl v chování mezi našimi klienty je výsledkem knihoven, které jsme použili pro naše implementace.
Další materiály
Tento článek předpokládá, že čtenář je obeznámen s tématy popsanými v tématu Začínáme s ASP.NET Core SignalR.
Co je MessagePack?
MessagePack je rychlý a kompaktní binární serializační formát. Je užitečné, když je výkon a šířka pásma problém, protože ve srovnání s JSON vytváří menší zprávy. Binární zprávy jsou při pohledu na trasování sítě a protokoly nečitelné, pokud nejsou bajty předány prostřednictvím analyzátoru MessagePack. SignalR má integrovanou podporu pro formát MessagePack a poskytuje rozhraní API pro použití klienta a serveru.
Konfigurace balíčku MessagePack na serveru
Pokud chcete na serveru povolit protokol MessagePack Hub, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček do aplikace. Startup.ConfigureServices
V metodě přidejte AddMessagePackProtocol
do AddSignalR
volání povolení podpory MessagePack na serveru.
Poznámka:
Json je ve výchozím nastavení povolený. Přidání MessagePacku umožňuje podporu pro klienty JSON i MessagePack.
services.AddSignalR()
.AddMessagePackProtocol();
Pokud chcete přizpůsobit, jak bude MessagePack formátovat vaše data, AddMessagePackProtocol
vezme delegáta pro konfiguraci možností. V daném delegátu FormatterResolvers
lze vlastnost použít ke konfiguraci možností serializace MessagePack. Další informace o tom, jak překladače fungují, naleznete v knihovně MessagePack na MessagePack-CSharp. Atributy lze použít u objektů, které chcete serializovat, a definovat, jak mají být zpracovány.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.StandardResolver.Instance
};
});
Upozorňující
Důrazně doporučujeme zkontrolovat CVE-2020-5234 a použít doporučené opravy. Můžete například nastavit statickou MessagePackSecurity.Active
vlastnost na MessagePackSecurity.UntrustedData
hodnotu . MessagePackSecurity.Active
Nastavení vyžaduje ruční instalaci verze MessagePack 1.9.x. Instalace MessagePack
verze 1.9.x upgraduje SignalR verzi. MessagePack
verze 2.x zavedla zásadní změny a není kompatibilní s verzemi SignalR 3.1 a staršími. Pokud MessagePackSecurity.Active
není nastavená hodnota MessagePackSecurity.UntrustedData
, může škodlivý klient způsobit odepření služby. Nastavit MessagePackSecurity.Active
v Program.Main
, jak je znázorněno v následujícím kódu:
using MessagePack;
public static void Main(string[] args)
{
MessagePackSecurity.Active = MessagePackSecurity.UntrustedData;
CreateHostBuilder(args).Build().Run();
}
Konfigurace balíčku MessagePack v klientovi
Poznámka:
Pro podporované klienty je ve výchozím nastavení povolený JSON. Klienti můžou podporovat pouze jeden protokol. Přidání podpory MessagePacku nahradí všechny dříve nakonfigurované protokoly.
Klient .NET
Chcete-li povolit MessagePack v klientovi .NET, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček a volání AddMessagePackProtocol
.HubConnectionBuilder
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Poznámka:
Toto AddMessagePackProtocol
volání přebírá delegáta pro konfiguraci možností stejně jako server.
Javascriptový klient
Podpora MessagePacku pro klienta JavaScriptu je poskytována balíčkem npm @microsoft/signalr-protocol-msgpack npm. Nainstalujte balíček spuštěním následujícího příkazu v příkazovém prostředí:
npm install @microsoft/signalr-protocol-msgpack
Po instalaci balíčku npm je možné modul použít přímo přes zavaděč modulu JavaScript nebo importovat do prohlížeče odkazováním na následující soubor:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
V prohlížeči se na knihovnu msgpack5
musí odkazovat také. <script>
K vytvoření odkazu použijte značku. Knihovnu najdete na adrese node_modules\msgpack5\dist\msgpack5.js.
Poznámka:
Při použití elementu <script>
je pořadí důležité. Pokud signalr-protocol-msgpack.js
se odkazuje dříve msgpack5.js
, při pokusu o připojení pomocí MessagePacku dojde k chybě. signalr.js
je rovněž vyžadována před signalr-protocol-msgpack.js
.
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/msgpack5/msgpack5.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
Přidání .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
do HubConnectionBuilder
konfigurace klienta pro použití protokolu MessagePack při připojování k serveru.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Poznámka:
V tuto chvíli neexistují žádné možnosti konfigurace protokolu MessagePack v javascriptovém klientovi.
Důležité informace o balíčku MessagePack
Při použití protokolu MessagePack Hub je potřeba mít na paměti několik problémů.
MessagePack rozlišují malá a velká písmena.
V protokolu MessagePack se rozlišují malá a velká písmena. Představte si například následující třídu jazyka C#:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Při odesílání z klienta JavaScriptu musíte použít PascalCased
názvy vlastností, protože velikost písmen musí přesně odpovídat třídě jazyka C#. Příklad:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Použití camelCased
názvů nebude správně svázané s třídou jazyka C#. Tento problém můžete obejít pomocí atributu Key
, který určuje jiný název vlastnosti MessagePack. Další informace najdete v dokumentaci MessagePack-CSharp.
DateTime.Kind se nezachová při serializaci/deserializaci
Protokol MessagePack neposkytuje způsob kódování Kind
hodnoty DateTime
. V důsledku toho při deserializaci data protokol centra MessagePack předpokládá, že příchozí datum je ve formátu UTC. Pokud pracujete s DateTime
hodnotami v místním čase, doporučujeme před jejich odesláním převést na UTC. Převeďte je z UTC na místní čas, když je obdržíte.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2632.
MessagePack v JavaScriptu nepodporuje DateTime.MinValue
Knihovna msgpack5 používaná klientem SignalR JavaScriptu nepodporuje timestamp96
typ v MessagePacku. Tento typ se používá ke kódování velmi velkých hodnot kalendářních dat (buď velmi brzy v minulosti, nebo velmi daleko v budoucnu). Hodnota DateTime.MinValue
je January 1, 0001
, která musí být kódována v hodnotě timestamp96
. Z tohoto důvodu se odesílání DateTime.MinValue
do javascriptového klienta nepodporuje. Při DateTime.MinValue
přijetí javascriptovým klientem se vyvolá následující chyba:
Uncaught Error: unable to find ext type 255 at decoder.js:427
DateTime.MinValue
Obvykle se používá ke kódování "chybějící" nebo null
hodnoty. Pokud potřebujete tuto hodnotu zakódovat v balíčku MessagePack, použijte hodnotu nullable DateTime
(DateTime?
) nebo zakódujte samostatnou bool
hodnotu označující, jestli je datum k dispozici.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2228.
Podpora MessagePacku v prostředí kompilace s předstihem
Knihovna MessagePack-CSharp používaná klientem a serverem .NET používá generování kódu k optimalizaci serializace. V důsledku toho se ve výchozím nastavení nepodporuje v prostředích, která používají kompilaci s předstihem (například Xamarin iOS nebo Unity). MessagePack je možné v těchto prostředích použít "předgenerováním" serializátoru/deserializátoru. Další informace najdete v dokumentaci MessagePack-CSharp. Jakmile serializátory předem vygenerujete, můžete je zaregistrovat pomocí delegáta konfigurace předaného do AddMessagePackProtocol
:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
};
});
Kontroly typů jsou v balíčku MessagePack přísnější.
Protokol CENTRA JSON provede převody typů během deserializace. Pokud například příchozí objekt má hodnotu vlastnosti, která je číslo ({ foo: 42 }
), ale vlastnost třídy .NET je typu string
, hodnota bude převedena. MessagePack však tento převod neprovádí a vyvolá výjimku, která se dá zobrazit v protokolech na straně serveru (a v konzole):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2937.
Další materiály
Tento článek předpokládá, že čtenář je obeznámen s tématy popsanými v tématu Začínáme s ASP.NET Core SignalR.
Co je MessagePack?
MessagePack je rychlý a kompaktní binární serializační formát. Je užitečné, když je výkon a šířka pásma problém, protože ve srovnání s JSON vytváří menší zprávy. Binární zprávy jsou při pohledu na trasování sítě a protokoly nečitelné, pokud nejsou bajty předány prostřednictvím analyzátoru MessagePack. SignalR má integrovanou podporu pro formát MessagePack a poskytuje rozhraní API pro použití klienta a serveru.
Konfigurace balíčku MessagePack na serveru
Pokud chcete na serveru povolit protokol MessagePack Hub, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček do aplikace. Startup.ConfigureServices
V metodě přidejte AddMessagePackProtocol
do AddSignalR
volání povolení podpory MessagePack na serveru.
Poznámka:
Json je ve výchozím nastavení povolený. Přidání MessagePacku umožňuje podporu pro klienty JSON i MessagePack.
services.AddSignalR()
.AddMessagePackProtocol();
Pokud chcete přizpůsobit, jak bude MessagePack formátovat vaše data, AddMessagePackProtocol
vezme delegáta pro konfiguraci možností. V daném delegátu FormatterResolvers
lze vlastnost použít ke konfiguraci možností serializace MessagePack. Další informace o tom, jak překladače fungují, naleznete v knihovně MessagePack na MessagePack-CSharp. Atributy lze použít u objektů, které chcete serializovat, a definovat, jak mají být zpracovány.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.StandardResolver.Instance
};
});
Upozorňující
Důrazně doporučujeme zkontrolovat CVE-2020-5234 a použít doporučené opravy. Můžete například nastavit statickou MessagePackSecurity.Active
vlastnost na MessagePackSecurity.UntrustedData
hodnotu . MessagePackSecurity.Active
Nastavení vyžaduje ruční instalaci verze MessagePack 1.9.x. Instalace MessagePack
verze 1.9.x upgraduje SignalR verzi. Pokud MessagePackSecurity.Active
není nastavená hodnota MessagePackSecurity.UntrustedData
, může škodlivý klient způsobit odepření služby. Nastavit MessagePackSecurity.Active
v Program.Main
, jak je znázorněno v následujícím kódu:
using MessagePack;
public static void Main(string[] args)
{
MessagePackSecurity.Active = MessagePackSecurity.UntrustedData;
CreateHostBuilder(args).Build().Run();
}
Konfigurace balíčku MessagePack v klientovi
Poznámka:
Pro podporované klienty je ve výchozím nastavení povolený JSON. Klienti můžou podporovat pouze jeden protokol. Přidání podpory MessagePacku nahradí všechny dříve nakonfigurované protokoly.
Klient .NET
Chcete-li povolit MessagePack v klientovi .NET, nainstalujte Microsoft.AspNetCore.SignalR.Protocols.MessagePack
balíček a volání AddMessagePackProtocol
.HubConnectionBuilder
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Poznámka:
Toto AddMessagePackProtocol
volání přebírá delegáta pro konfiguraci možností stejně jako server.
Javascriptový klient
Podpora MessagePacku pro klienta JavaScriptu je poskytována balíčkem npm @aspnet/signalr-protocol-msgpack npm. Nainstalujte balíček spuštěním následujícího příkazu v příkazovém prostředí:
npm install @aspnet/signalr-protocol-msgpack
Po instalaci balíčku npm je možné modul použít přímo přes zavaděč modulu JavaScript nebo importovat do prohlížeče odkazováním na následující soubor:
node_modules\@aspnet\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
V prohlížeči se na knihovnu msgpack5
musí odkazovat také. <script>
K vytvoření odkazu použijte značku. Knihovnu najdete na adrese node_modules\msgpack5\dist\msgpack5.js.
Poznámka:
Při použití elementu <script>
je pořadí důležité. Pokud signalr-protocol-msgpack.js
se odkazuje dříve msgpack5.js
, při pokusu o připojení pomocí MessagePacku dojde k chybě. signalr.js
je rovněž vyžadována před signalr-protocol-msgpack.js
.
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/msgpack5/msgpack5.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
Přidání .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
do HubConnectionBuilder
konfigurace klienta pro použití protokolu MessagePack při připojování k serveru.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Poznámka:
V tuto chvíli neexistují žádné možnosti konfigurace protokolu MessagePack v javascriptovém klientovi.
Důležité informace o balíčku MessagePack
Při použití protokolu MessagePack Hub je potřeba mít na paměti několik problémů.
MessagePack rozlišují malá a velká písmena.
V protokolu MessagePack se rozlišují malá a velká písmena. Představte si například následující třídu jazyka C#:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Při odesílání z klienta JavaScriptu musíte použít PascalCased
názvy vlastností, protože velikost písmen musí přesně odpovídat třídě jazyka C#. Příklad:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Použití camelCased
názvů nebude správně svázané s třídou jazyka C#. Tento problém můžete obejít pomocí atributu Key
, který určuje jiný název vlastnosti MessagePack. Další informace najdete v dokumentaci MessagePack-CSharp.
DateTime.Kind se nezachová při serializaci/deserializaci
Protokol MessagePack neposkytuje způsob kódování Kind
hodnoty DateTime
. V důsledku toho při deserializaci data protokol centra MessagePack předpokládá, že příchozí datum je ve formátu UTC. Pokud pracujete s DateTime
hodnotami v místním čase, doporučujeme před jejich odesláním převést na UTC. Převeďte je z UTC na místní čas, když je obdržíte.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2632.
MessagePack v JavaScriptu nepodporuje DateTime.MinValue
Knihovna msgpack5 používaná klientem SignalR JavaScriptu nepodporuje timestamp96
typ v MessagePacku. Tento typ se používá ke kódování velmi velkých hodnot kalendářních dat (buď velmi brzy v minulosti, nebo velmi daleko v budoucnu). Hodnota, January 1, 0001
která DateTime.MinValue
musí být zakódována v hodnotětimestamp96
. Z tohoto důvodu se odesílání DateTime.MinValue
do javascriptového klienta nepodporuje. Při DateTime.MinValue
přijetí javascriptovým klientem se vyvolá následující chyba:
Uncaught Error: unable to find ext type 255 at decoder.js:427
DateTime.MinValue
Obvykle se používá ke kódování "chybějící" nebo null
hodnoty. Pokud potřebujete tuto hodnotu zakódovat v balíčku MessagePack, použijte hodnotu nullable DateTime
(DateTime?
) nebo zakódujte samostatnou bool
hodnotu označující, jestli je datum k dispozici.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2228.
Podpora MessagePacku v prostředí kompilace s předstihem
Knihovna MessagePack-CSharp používaná klientem a serverem .NET používá generování kódu k optimalizaci serializace. V důsledku toho se ve výchozím nastavení nepodporuje v prostředích, která používají kompilaci s předstihem (například Xamarin iOS nebo Unity). MessagePack je možné v těchto prostředích použít "předgenerováním" serializátoru/deserializátoru. Další informace najdete v dokumentaci MessagePack-CSharp. Jakmile serializátory předem vygenerujete, můžete je zaregistrovat pomocí delegáta konfigurace předaného do AddMessagePackProtocol
:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
};
});
Kontroly typů jsou v balíčku MessagePack přísnější.
Protokol CENTRA JSON provede převody typů během deserializace. Pokud například příchozí objekt má hodnotu vlastnosti, která je číslo ({ foo: 42 }
), ale vlastnost třídy .NET je typu string
, hodnota bude převedena. MessagePack však tento převod neprovádí a vyvolá výjimku, která se dá zobrazit v protokolech na straně serveru (a v konzole):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Další informace o tomto omezení najdete v tématu Problém s GitHubem aspnet/SignalR#2937.