Gunakan MessagePack Hub Protocol di SignalR untuk ASP.NET Core
Artikel ini mengasumsikan pembaca terbiasa dengan topik yang dibahas dalam Memulai ASP.NET Core SignalR.
Apa itu MessagePack?
MessagePack adalah format serialisasi biner yang cepat dan ringkas. Ini berguna ketika performa dan bandwidth menjadi perhatian karena menciptakan pesan yang lebih kecil daripada JSON. Pesan biner tidak dapat dibaca saat melihat jejak jaringan dan log kecuali byte diteruskan melalui parser MessagePack. SignalR memiliki dukungan bawaan untuk format MessagePack dan menyediakan API untuk digunakan klien dan server.
Mengonfigurasi MessagePack di server
Untuk mengaktifkan Protokol Hub MessagePack di server, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket di aplikasi Anda. Dalam metode , Startup.ConfigureServices
tambahkan AddMessagePackProtocol
ke AddSignalR
panggilan untuk mengaktifkan dukungan MessagePack di server.
services.AddSignalR()
.AddMessagePackProtocol();
Catatan
JSON diaktifkan secara default. Menambahkan MessagePack memungkinkan dukungan untuk klien JSON dan MessagePack.
Untuk menyesuaikan bagaimana MessagePack memformat data, AddMessagePackProtocol
ambil delegasi untuk mengonfigurasi opsi. Dalam delegasi tersebut SerializerOptions
, properti digunakan untuk mengonfigurasi opsi serialisasi MessagePack. Untuk informasi selengkapnya tentang cara kerja pemecah masalah, kunjungi pustaka MessagePack di MessagePack-CSharp. Atribut dapat digunakan pada objek yang ingin Anda serialkan untuk menentukan bagaimana atribut tersebut harus ditangani.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(new CustomResolver())
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Peringatan
Kami sangat menyarankan untuk meninjau CVE-2020-5234 dan menerapkan patch yang direkomendasikan. Misalnya, memanggil .WithSecurity(MessagePackSecurity.UntrustedData)
saat mengganti SerializerOptions
.
Mengonfigurasi MessagePack pada klien
Catatan
JSON diaktifkan secara default untuk klien yang didukung. Klien hanya dapat mendukung satu protokol. Menambahkan dukungan MessagePack menggantikan protokol yang dikonfigurasi sebelumnya.
Klien .NET
Untuk mengaktifkan MessagePack di Klien .NET, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket dan panggil AddMessagePackProtocol
di HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Catatan
Panggilan ini AddMessagePackProtocol
mengambil delegasi untuk mengonfigurasi opsi seperti server.
Klien JavaScript
Dukungan MessagePack untuk klien JavaScript disediakan oleh paket npm @microsoft/signalr-protocol-msgpack . Instal paket dengan menjalankan perintah berikut dalam shell perintah:
npm install @microsoft/signalr-protocol-msgpack
Setelah menginstal paket npm, modul dapat digunakan langsung melalui pemuat modul JavaScript atau diimpor ke browser dengan mereferensikan file berikut:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
File javaScript yang diperlukan berikut harus direferensikan dalam urutan yang ditunjukkan di bawah ini:
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
Menambahkan ke HubConnectionBuilder
konfigurasi klien untuk menggunakan protokol MessagePack saat menyambungkan ke server.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Saat ini, tidak ada opsi konfigurasi untuk protokol MessagePack pada klien JavaScript.
Klien Java
Untuk mengaktifkan MessagePack dengan Java, instal com.microsoft.signalr.messagepack
paket. Saat menggunakan Gradle, tambahkan baris berikut ke bagian dependencies
file build.gradle :
implementation 'com.microsoft.signalr.messagepack:signalr-messagepack:5.0.0'
Saat menggunakan Maven, tambahkan baris berikut di <dependencies>
dalam elemen pom.xml
file:
<dependency>
<groupId>com.microsoft.signalr.messagepack</groupId>
<artifactId>signalr</artifactId>
<version>5.0.0</version>
</dependency>
Panggil withHubProtocol(new MessagePackHubProtocol())
di HubConnectionBuilder
.
HubConnection messagePackConnection = HubConnectionBuilder.create("YOUR HUB URL HERE")
.withHubProtocol(new MessagePackHubProtocol())
.build();
Pertimbangan MessagePack
Ada beberapa masalah yang perlu diperhatikan saat menggunakan Protokol Hub MessagePack.
MessagePack peka huruf besar/kecil
Protokol MessagePack peka huruf besar/kecil. Misalnya, pertimbangkan kelas C# berikut:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Saat mengirim dari klien JavaScript, Anda harus menggunakan PascalCased
nama properti, karena casing harus sama persis dengan kelas C#. Contohnya:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Menggunakan camelCased
nama tidak akan terikat dengan benar ke kelas C#. Anda dapat mengatasinya dengan menggunakan Key
atribut untuk menentukan nama yang berbeda untuk properti MessagePack. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp.
DateTime.Kind tidak dipertahankan saat serialisasi/deserialisasi
Protokol MessagePack tidak menyediakan cara untuk mengodekan Kind
DateTime
nilai . Akibatnya, ketika mendeserialisasi tanggal, Protokol MessagePack Hub akan mengonversi ke format UTC jika DateTime.Kind
sebaliknya DateTimeKind.Local
tidak akan menyentuh waktu dan meneruskannya apa adanya. Jika Anda bekerja dengan DateTime
nilai, sebaiknya konversi ke UTC sebelum mengirimkannya. Konversikan dari UTC ke waktu lokal saat Anda menerimanya.
Dukungan MessagePack di lingkungan kompilasi "sebelumnya"
Pustaka MessagePack-CSharp yang digunakan oleh klien .NET dan server menggunakan pembuatan kode untuk mengoptimalkan serialisasi. Akibatnya, ini tidak didukung secara default pada lingkungan yang menggunakan kompilasi "ahead-of-time" (seperti Xamarin iOS atau Unity). Dimungkinkan untuk menggunakan MessagePack di lingkungan ini dengan "pra-pembuatan" kode serializer/deserializer. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp. Setelah membuat serializer sebelumnya, Anda dapat mendaftarkannya menggunakan delegasi konfigurasi yang diteruskan ke 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);
});
Pemeriksaan jenis lebih ketat di MessagePack
Protokol Hub JSON akan melakukan konversi jenis selama deserialisasi. Misalnya, jika objek masuk memiliki nilai properti yang merupakan angka ({ foo: 42 }
) tetapi properti pada kelas .NET berjenis string
, nilai akan dikonversi. Namun, MessagePack tidak melakukan konversi ini dan akan melemparkan pengecualian yang dapat dilihat di log sisi server (dan di konsol):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2937.
Karakter dan String di Java
Di klien java, char
objek akan diserialisasikan sebagai objek satu karakter String
. Ini berbeda dengan klien C# dan JavaScript, yang menserialisasikannya sebagai short
objek. Spesifikasi MessagePack itu sendiri tidak menentukan perilaku untuk char
objek, jadi terserah penulis pustaka untuk menentukan cara menserialisasikannya. Perbedaan perilaku antara klien kami adalah hasil dari pustaka yang kami gunakan untuk implementasi kami.
Sumber Daya Tambahan:
Artikel ini mengasumsikan pembaca terbiasa dengan topik yang dibahas dalam Memulai ASP.NET Core SignalR.
Apa itu MessagePack?
MessagePack adalah format serialisasi biner yang cepat dan ringkas. Ini berguna ketika performa dan bandwidth menjadi perhatian karena menciptakan pesan yang lebih kecil dibandingkan dengan JSON. Pesan biner tidak dapat dibaca saat melihat jejak jaringan dan log kecuali byte diteruskan melalui parser MessagePack. SignalR memiliki dukungan bawaan untuk format MessagePack dan menyediakan API untuk digunakan klien dan server.
Mengonfigurasi MessagePack di server
Untuk mengaktifkan Protokol Hub MessagePack di server, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket di aplikasi Anda. Dalam metode , Startup.ConfigureServices
tambahkan AddMessagePackProtocol
ke AddSignalR
panggilan untuk mengaktifkan dukungan MessagePack di server.
Catatan
JSON diaktifkan secara default. Menambahkan MessagePack memungkinkan dukungan untuk klien JSON dan MessagePack.
services.AddSignalR()
.AddMessagePackProtocol();
Untuk menyesuaikan bagaimana MessagePack akan memformat data Anda, AddMessagePackProtocol
ambil delegasi untuk mengonfigurasi opsi. Dalam delegasi tersebut SerializerOptions
, properti dapat digunakan untuk mengonfigurasi opsi serialisasi MessagePack. Untuk informasi selengkapnya tentang cara kerja pemecah masalah, kunjungi pustaka MessagePack di MessagePack-CSharp. Atribut dapat digunakan pada objek yang ingin Anda serialkan untuk menentukan bagaimana atribut tersebut harus ditangani.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(new CustomResolver())
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Peringatan
Kami sangat menyarankan untuk meninjau CVE-2020-5234 dan menerapkan patch yang direkomendasikan. Misalnya, memanggil .WithSecurity(MessagePackSecurity.UntrustedData)
saat mengganti SerializerOptions
.
Mengonfigurasi MessagePack pada klien
Catatan
JSON diaktifkan secara default untuk klien yang didukung. Klien hanya dapat mendukung satu protokol. Menambahkan dukungan MessagePack akan menggantikan protokol yang dikonfigurasi sebelumnya.
Klien .NET
Untuk mengaktifkan MessagePack di Klien .NET, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket dan panggil AddMessagePackProtocol
di HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Catatan
Panggilan ini AddMessagePackProtocol
mengambil delegasi untuk mengonfigurasi opsi seperti server.
Klien JavaScript
Dukungan MessagePack untuk klien JavaScript disediakan oleh paket npm @microsoft/signalr-protocol-msgpack . Instal paket dengan menjalankan perintah berikut dalam shell perintah:
npm install @microsoft/signalr-protocol-msgpack
Setelah menginstal paket npm, modul dapat digunakan langsung melalui pemuat modul JavaScript atau diimpor ke browser dengan mereferensikan file berikut:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Di browser, msgpack5
pustaka juga harus dirujuk. <script>
Gunakan tag untuk membuat referensi. Pustaka dapat ditemukan di node_modules\msgpack5\dist\msgpack5.js.
Catatan
Saat menggunakan <script>
elemen , urutannya penting. Jika signalr-protocol-msgpack.js
dirujuk sebelum msgpack5.js
, kesalahan terjadi saat mencoba terhubung dengan MessagePack. signalr.js
juga diperlukan sebelum 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>
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
Menambahkan ke HubConnectionBuilder
akan mengonfigurasi klien untuk menggunakan protokol MessagePack saat menyambungkan ke server.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Catatan
Saat ini, tidak ada opsi konfigurasi untuk protokol MessagePack pada klien JavaScript.
Klien Java
Untuk mengaktifkan MessagePack dengan Java, instal com.microsoft.signalr.messagepack
paket. Saat menggunakan Gradle, tambahkan baris berikut ke bagian dependencies
file build.gradle :
implementation 'com.microsoft.signalr.messagepack:signalr-messagepack:5.0.0'
Saat menggunakan Maven, tambahkan baris berikut di <dependencies>
dalam elemen pom.xml
file:
<dependency>
<groupId>com.microsoft.signalr.messagepack</groupId>
<artifactId>signalr</artifactId>
<version>5.0.0</version>
</dependency>
Panggil withHubProtocol(new MessagePackHubProtocol())
di HubConnectionBuilder
.
HubConnection messagePackConnection = HubConnectionBuilder.create("YOUR HUB URL HERE")
.withHubProtocol(new MessagePackHubProtocol())
.build();
Pertimbangan MessagePack
Ada beberapa masalah yang perlu diperhatikan saat menggunakan Protokol Hub MessagePack.
MessagePack peka huruf besar/kecil
Protokol MessagePack peka huruf besar/kecil. Misalnya, pertimbangkan kelas C# berikut:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Saat mengirim dari klien JavaScript, Anda harus menggunakan PascalCased
nama properti, karena casing harus sama persis dengan kelas C#. Contohnya:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Menggunakan camelCased
nama tidak akan terikat dengan benar ke kelas C#. Anda dapat mengatasinya dengan menggunakan Key
atribut untuk menentukan nama yang berbeda untuk properti MessagePack. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp.
DateTime.Kind tidak dipertahankan saat serialisasi/deserialisasi
Protokol MessagePack tidak menyediakan cara untuk mengodekan Kind
DateTime
nilai . Akibatnya, ketika mendeserialisasi tanggal, Protokol MessagePack Hub akan mengonversi ke format UTC jika DateTime.Kind
sebaliknya DateTimeKind.Local
tidak akan menyentuh waktu dan meneruskannya apa adanya. Jika Anda bekerja dengan DateTime
nilai, sebaiknya konversi ke UTC sebelum mengirimkannya. Konversikan dari UTC ke waktu lokal saat Anda menerimanya.
DateTime.MinValue tidak didukung oleh MessagePack di JavaScript
Pustaka msgpack5 yang digunakan oleh SignalR klien JavaScript tidak mendukung timestamp96
jenis di MessagePack. Jenis ini digunakan untuk mengodekan nilai tanggal yang sangat besar (baik sangat awal di masa lalu atau sangat jauh di masa depan). Nilai DateTime.MinValue
adalah January 1, 0001
, yang harus dikodekan dalam nilai timestamp96
. Karena itu, pengiriman DateTime.MinValue
ke klien JavaScript tidak didukung. Ketika DateTime.MinValue
diterima oleh klien JavaScript, kesalahan berikut dilemparkan:
Uncaught Error: unable to find ext type 255 at decoder.js:427
Biasanya, DateTime.MinValue
digunakan untuk mengodekan "hilang" atau null
nilai. Jika Anda perlu mengodekan nilai tersebut di MessagePack, gunakan nilai nullable DateTime
(DateTime?
) atau enkode nilai terpisah bool
yang menunjukkan apakah tanggal ada.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2228.
Dukungan MessagePack di lingkungan kompilasi "sebelumnya"
Pustaka MessagePack-CSharp yang digunakan oleh klien .NET dan server menggunakan pembuatan kode untuk mengoptimalkan serialisasi. Akibatnya, ini tidak didukung secara default pada lingkungan yang menggunakan kompilasi "ahead-of-time" (seperti Xamarin iOS atau Unity). Dimungkinkan untuk menggunakan MessagePack di lingkungan ini dengan "pra-pembuatan" kode serializer/deserializer. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp. Setelah membuat serializer sebelumnya, Anda dapat mendaftarkannya menggunakan delegasi konfigurasi yang diteruskan ke 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);
});
Pemeriksaan jenis lebih ketat di MessagePack
Protokol Hub JSON akan melakukan konversi jenis selama deserialisasi. Misalnya, jika objek masuk memiliki nilai properti yang merupakan angka ({ foo: 42 }
) tetapi properti pada kelas .NET berjenis string
, nilai akan dikonversi. Namun, MessagePack tidak melakukan konversi ini dan akan melemparkan pengecualian yang dapat dilihat di log sisi server (dan di konsol):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2937.
Karakter dan String di Java
Di klien java, char
objek akan diserialisasikan sebagai objek satu karakter String
. Ini berbeda dengan klien C# dan JavaScript, yang menserialisasikannya sebagai short
objek. Spesifikasi MessagePack itu sendiri tidak menentukan perilaku untuk char
objek, jadi terserah penulis pustaka untuk menentukan cara menserialisasikannya. Perbedaan perilaku antara klien kami adalah hasil dari pustaka yang kami gunakan untuk implementasi kami.
Sumber Daya Tambahan:
Artikel ini mengasumsikan pembaca terbiasa dengan topik yang dibahas dalam Memulai ASP.NET Core SignalR.
Apa itu MessagePack?
MessagePack adalah format serialisasi biner yang cepat dan ringkas. Ini berguna ketika performa dan bandwidth menjadi perhatian karena menciptakan pesan yang lebih kecil dibandingkan dengan JSON. Pesan biner tidak dapat dibaca saat melihat jejak jaringan dan log kecuali byte diteruskan melalui parser MessagePack. SignalR memiliki dukungan bawaan untuk format MessagePack, dan menyediakan API untuk digunakan klien dan server.
Mengonfigurasi MessagePack di server
Untuk mengaktifkan Protokol Hub MessagePack di server, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket di aplikasi Anda. Dalam metode , Startup.ConfigureServices
tambahkan AddMessagePackProtocol
ke AddSignalR
panggilan untuk mengaktifkan dukungan MessagePack di server.
Catatan
JSON diaktifkan secara default. Menambahkan MessagePack memungkinkan dukungan untuk klien JSON dan MessagePack.
services.AddSignalR()
.AddMessagePackProtocol();
Untuk menyesuaikan bagaimana MessagePack akan memformat data Anda, AddMessagePackProtocol
ambil delegasi untuk mengonfigurasi opsi. Dalam delegasi tersebut FormatterResolvers
, properti dapat digunakan untuk mengonfigurasi opsi serialisasi MessagePack. Untuk informasi selengkapnya tentang cara kerja pemecah masalah, kunjungi pustaka MessagePack di MessagePack-CSharp. Atribut dapat digunakan pada objek yang ingin Anda serialkan untuk menentukan bagaimana atribut tersebut harus ditangani.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.StandardResolver.Instance
};
});
Peringatan
Kami sangat menyarankan untuk meninjau CVE-2020-5234 dan menerapkan patch yang direkomendasikan. Misalnya, atur MessagePackSecurity.Active
properti statis ke MessagePackSecurity.UntrustedData
. MessagePackSecurity.Active
Mengatur persyaratan menginstal MessagePack versi 1.9.x secara manual. MessagePack
Menginstal 1.9.x meningkatkan versi SignalR yang digunakan. MessagePack
versi 2.x memperkenalkan perubahan melanggar dan tidak kompatibel dengan SignalR versi 3.1 dan yang lebih lama. Ketika MessagePackSecurity.Active
tidak diatur ke MessagePackSecurity.UntrustedData
, klien berbahaya dapat menyebabkan penolakan layanan. Atur MessagePackSecurity.Active
di Program.Main
, seperti yang ditunjukkan dalam kode berikut:
using MessagePack;
public static void Main(string[] args)
{
MessagePackSecurity.Active = MessagePackSecurity.UntrustedData;
CreateHostBuilder(args).Build().Run();
}
Mengonfigurasi MessagePack pada klien
Catatan
JSON diaktifkan secara default untuk klien yang didukung. Klien hanya dapat mendukung satu protokol. Menambahkan dukungan MessagePack akan menggantikan protokol yang dikonfigurasi sebelumnya.
Klien .NET
Untuk mengaktifkan MessagePack di Klien .NET, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket dan panggil AddMessagePackProtocol
di HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Catatan
Panggilan ini AddMessagePackProtocol
mengambil delegasi untuk mengonfigurasi opsi seperti server.
Klien JavaScript
Dukungan MessagePack untuk klien JavaScript disediakan oleh paket npm @microsoft/signalr-protocol-msgpack . Instal paket dengan menjalankan perintah berikut dalam shell perintah:
npm install @microsoft/signalr-protocol-msgpack
Setelah menginstal paket npm, modul dapat digunakan langsung melalui pemuat modul JavaScript atau diimpor ke browser dengan mereferensikan file berikut:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Di browser, msgpack5
pustaka juga harus dirujuk. <script>
Gunakan tag untuk membuat referensi. Pustaka dapat ditemukan di node_modules\msgpack5\dist\msgpack5.js.
Catatan
Saat menggunakan <script>
elemen , urutannya penting. Jika signalr-protocol-msgpack.js
dirujuk sebelum msgpack5.js
, kesalahan terjadi saat mencoba terhubung dengan MessagePack. signalr.js
juga diperlukan sebelum 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>
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
Menambahkan ke HubConnectionBuilder
akan mengonfigurasi klien untuk menggunakan protokol MessagePack saat menyambungkan ke server.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Catatan
Saat ini, tidak ada opsi konfigurasi untuk protokol MessagePack pada klien JavaScript.
Pertimbangan MessagePack
Ada beberapa masalah yang perlu diperhatikan saat menggunakan Protokol Hub MessagePack.
MessagePack peka huruf besar/kecil
Protokol MessagePack peka huruf besar/kecil. Misalnya, pertimbangkan kelas C# berikut:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Saat mengirim dari klien JavaScript, Anda harus menggunakan PascalCased
nama properti, karena casing harus sama persis dengan kelas C#. Contohnya:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Menggunakan camelCased
nama tidak akan terikat dengan benar ke kelas C#. Anda dapat mengatasinya dengan menggunakan Key
atribut untuk menentukan nama yang berbeda untuk properti MessagePack. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp.
DateTime.Kind tidak dipertahankan saat serialisasi/deserialisasi
Protokol MessagePack tidak menyediakan cara untuk mengodekan Kind
DateTime
nilai . Akibatnya, saat mendeserialisasi tanggal, Protokol Hub MessagePack mengasumsikan tanggal masuk dalam format UTC. Jika Anda bekerja dengan DateTime
nilai di waktu lokal, sebaiknya konversi ke UTC sebelum mengirimkannya. Konversikan dari UTC ke waktu lokal saat Anda menerimanya.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2632.
DateTime.MinValue tidak didukung oleh MessagePack di JavaScript
Pustaka msgpack5 yang digunakan oleh SignalR klien JavaScript tidak mendukung timestamp96
jenis di MessagePack. Jenis ini digunakan untuk mengodekan nilai tanggal yang sangat besar (baik sangat awal di masa lalu atau sangat jauh di masa depan). Nilai DateTime.MinValue
adalah January 1, 0001
, yang harus dikodekan dalam nilai timestamp96
. Karena itu, pengiriman DateTime.MinValue
ke klien JavaScript tidak didukung. Ketika DateTime.MinValue
diterima oleh klien JavaScript, kesalahan berikut dilemparkan:
Uncaught Error: unable to find ext type 255 at decoder.js:427
Biasanya, DateTime.MinValue
digunakan untuk mengodekan "hilang" atau null
nilai. Jika Anda perlu mengodekan nilai tersebut di MessagePack, gunakan nilai nullable DateTime
(DateTime?
) atau enkode nilai terpisah bool
yang menunjukkan apakah tanggal ada.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2228.
Dukungan MessagePack di lingkungan kompilasi "sebelumnya"
Pustaka MessagePack-CSharp yang digunakan oleh klien .NET dan server menggunakan pembuatan kode untuk mengoptimalkan serialisasi. Akibatnya, ini tidak didukung secara default pada lingkungan yang menggunakan kompilasi "ahead-of-time" (seperti Xamarin iOS atau Unity). Dimungkinkan untuk menggunakan MessagePack di lingkungan ini dengan "pra-pembuatan" kode serializer/deserializer. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp. Setelah membuat serializer sebelumnya, Anda dapat mendaftarkannya menggunakan delegasi konfigurasi yang diteruskan ke AddMessagePackProtocol
:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
};
});
Pemeriksaan jenis lebih ketat di MessagePack
Protokol Hub JSON akan melakukan konversi jenis selama deserialisasi. Misalnya, jika objek masuk memiliki nilai properti yang merupakan angka ({ foo: 42 }
) tetapi properti pada kelas .NET berjenis string
, nilai akan dikonversi. Namun, MessagePack tidak melakukan konversi ini dan akan melemparkan pengecualian yang dapat dilihat di log sisi server (dan di konsol):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2937.
Sumber Daya Tambahan:
Artikel ini mengasumsikan pembaca terbiasa dengan topik yang dibahas dalam Memulai ASP.NET Core SignalR.
Apa itu MessagePack?
MessagePack adalah format serialisasi biner yang cepat dan ringkas. Ini berguna ketika performa dan bandwidth menjadi perhatian karena menciptakan pesan yang lebih kecil dibandingkan dengan JSON. Pesan biner tidak dapat dibaca saat melihat jejak jaringan dan log kecuali byte diteruskan melalui parser MessagePack. SignalR memiliki dukungan bawaan untuk format MessagePack, dan menyediakan API untuk digunakan klien dan server.
Mengonfigurasi MessagePack di server
Untuk mengaktifkan Protokol Hub MessagePack di server, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket di aplikasi Anda. Dalam metode , Startup.ConfigureServices
tambahkan AddMessagePackProtocol
ke AddSignalR
panggilan untuk mengaktifkan dukungan MessagePack di server.
Catatan
JSON diaktifkan secara default. Menambahkan MessagePack memungkinkan dukungan untuk klien JSON dan MessagePack.
services.AddSignalR()
.AddMessagePackProtocol();
Untuk menyesuaikan bagaimana MessagePack akan memformat data Anda, AddMessagePackProtocol
ambil delegasi untuk mengonfigurasi opsi. Dalam delegasi tersebut FormatterResolvers
, properti dapat digunakan untuk mengonfigurasi opsi serialisasi MessagePack. Untuk informasi selengkapnya tentang cara kerja pemecah masalah, kunjungi pustaka MessagePack di MessagePack-CSharp. Atribut dapat digunakan pada objek yang ingin Anda serialkan untuk menentukan bagaimana atribut tersebut harus ditangani.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.StandardResolver.Instance
};
});
Peringatan
Kami sangat menyarankan untuk meninjau CVE-2020-5234 dan menerapkan patch yang direkomendasikan. Misalnya, atur MessagePackSecurity.Active
properti statis ke MessagePackSecurity.UntrustedData
. MessagePackSecurity.Active
Mengatur persyaratan menginstal MessagePack versi 1.9.x secara manual. MessagePack
Menginstal 1.9.x meningkatkan versi SignalR yang digunakan. Ketika MessagePackSecurity.Active
tidak diatur ke MessagePackSecurity.UntrustedData
, klien berbahaya dapat menyebabkan penolakan layanan. Atur MessagePackSecurity.Active
di Program.Main
, seperti yang ditunjukkan dalam kode berikut:
using MessagePack;
public static void Main(string[] args)
{
MessagePackSecurity.Active = MessagePackSecurity.UntrustedData;
CreateHostBuilder(args).Build().Run();
}
Mengonfigurasi MessagePack pada klien
Catatan
JSON diaktifkan secara default untuk klien yang didukung. Klien hanya dapat mendukung satu protokol. Menambahkan dukungan MessagePack akan menggantikan protokol yang dikonfigurasi sebelumnya.
Klien .NET
Untuk mengaktifkan MessagePack di Klien .NET, instal Microsoft.AspNetCore.SignalR.Protocols.MessagePack
paket dan panggil AddMessagePackProtocol
di HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Catatan
Panggilan ini AddMessagePackProtocol
mengambil delegasi untuk mengonfigurasi opsi seperti server.
Klien JavaScript
Dukungan MessagePack untuk klien JavaScript disediakan oleh paket npm @aspnet/signalr-protocol-msgpack . Instal paket dengan menjalankan perintah berikut dalam shell perintah:
npm install @aspnet/signalr-protocol-msgpack
Setelah menginstal paket npm, modul dapat digunakan langsung melalui pemuat modul JavaScript atau diimpor ke browser dengan mereferensikan file berikut:
node_modules\@aspnet\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Di browser, msgpack5
pustaka juga harus dirujuk. <script>
Gunakan tag untuk membuat referensi. Pustaka dapat ditemukan di node_modules\msgpack5\dist\msgpack5.js.
Catatan
Saat menggunakan <script>
elemen , urutannya penting. Jika signalr-protocol-msgpack.js
dirujuk sebelum msgpack5.js
, kesalahan terjadi saat mencoba terhubung dengan MessagePack. signalr.js
juga diperlukan sebelum 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>
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
Menambahkan ke HubConnectionBuilder
akan mengonfigurasi klien untuk menggunakan protokol MessagePack saat menyambungkan ke server.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Catatan
Saat ini, tidak ada opsi konfigurasi untuk protokol MessagePack pada klien JavaScript.
Pertimbangan MessagePack
Ada beberapa masalah yang perlu diperhatikan saat menggunakan Protokol Hub MessagePack.
MessagePack peka huruf besar/kecil
Protokol MessagePack peka huruf besar/kecil. Misalnya, pertimbangkan kelas C# berikut:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
Saat mengirim dari klien JavaScript, Anda harus menggunakan PascalCased
nama properti, karena casing harus sama persis dengan kelas C#. Contohnya:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Menggunakan camelCased
nama tidak akan terikat dengan benar ke kelas C#. Anda dapat mengatasinya dengan menggunakan Key
atribut untuk menentukan nama yang berbeda untuk properti MessagePack. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp.
DateTime.Kind tidak dipertahankan saat serialisasi/deserialisasi
Protokol MessagePack tidak menyediakan cara untuk mengodekan Kind
DateTime
nilai . Akibatnya, saat mendeserialisasi tanggal, Protokol Hub MessagePack mengasumsikan tanggal masuk dalam format UTC. Jika Anda bekerja dengan DateTime
nilai di waktu lokal, sebaiknya konversi ke UTC sebelum mengirimkannya. Konversikan dari UTC ke waktu lokal saat Anda menerimanya.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2632.
DateTime.MinValue tidak didukung oleh MessagePack di JavaScript
Pustaka msgpack5 yang digunakan oleh SignalR klien JavaScript tidak mendukung timestamp96
jenis di MessagePack. Jenis ini digunakan untuk mengodekan nilai tanggal yang sangat besar (baik sangat awal di masa lalu atau sangat jauh di masa depan). Nilai DateTime.MinValue
yang January 1, 0001
harus dikodekan dalam nilai timestamp96
. Karena itu, pengiriman DateTime.MinValue
ke klien JavaScript tidak didukung. Ketika DateTime.MinValue
diterima oleh klien JavaScript, kesalahan berikut dilemparkan:
Uncaught Error: unable to find ext type 255 at decoder.js:427
Biasanya, DateTime.MinValue
digunakan untuk mengodekan "hilang" atau null
nilai. Jika Anda perlu mengodekan nilai tersebut di MessagePack, gunakan nilai nullable DateTime
(DateTime?
) atau enkode nilai terpisah bool
yang menunjukkan apakah tanggal ada.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2228.
Dukungan MessagePack di lingkungan kompilasi "sebelumnya"
Pustaka MessagePack-CSharp yang digunakan oleh klien .NET dan server menggunakan pembuatan kode untuk mengoptimalkan serialisasi. Akibatnya, ini tidak didukung secara default pada lingkungan yang menggunakan kompilasi "ahead-of-time" (seperti Xamarin iOS atau Unity). Dimungkinkan untuk menggunakan MessagePack di lingkungan ini dengan "pra-pembuatan" kode serializer/deserializer. Untuk informasi selengkapnya, lihat dokumentasi MessagePack-CSharp. Setelah membuat serializer sebelumnya, Anda dapat mendaftarkannya menggunakan delegasi konfigurasi yang diteruskan ke AddMessagePackProtocol
:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
};
});
Pemeriksaan jenis lebih ketat di MessagePack
Protokol Hub JSON akan melakukan konversi jenis selama deserialisasi. Misalnya, jika objek masuk memiliki nilai properti yang merupakan angka ({ foo: 42 }
) tetapi properti pada kelas .NET berjenis string
, nilai akan dikonversi. Namun, MessagePack tidak melakukan konversi ini dan akan melemparkan pengecualian yang dapat dilihat di log sisi server (dan di konsol):
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Untuk informasi selengkapnya tentang batasan ini, lihat Masalah GitHub aspnet/SignalR#2937.
Sumber Daya Tambahan:
ASP.NET Core