ASP.NET Core için içinde SignalR MessagePack Hub Protokolü kullanma
Bu makalede, okuyucunun ASP.NET Core kullanmaya başlama başlığı altında ele alınan konulara aşina olduğu varsayılır SignalR.
MessagePack nedir?
MessagePack hızlı ve kompakt bir ikili serileştirme biçimidir. JSON'dan daha küçük iletiler oluşturduğundan performans ve bant genişliği önemli olduğunda kullanışlıdır. Baytlar bir MessagePack ayrıştırıcısı üzerinden geçirilmediği sürece, ağ izlemelerine ve günlüklerine bakılırken ikili iletiler okunamaz. SignalR MessagePack biçimi için yerleşik desteğe sahiptir ve istemci ve sunucunun kullanması için API'ler sağlar.
Sunucuda MessagePack'i yapılandırma
Sunucuda MessagePack Hub Protokolü'ni etkinleştirmek için paketi uygulamanıza yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
. yönteminde Startup.ConfigureServices
, sunucuda MessagePack desteğini etkinleştirmek için çağrısına ekleyin AddMessagePackProtocol
AddSignalR
.
services.AddSignalR()
.AddMessagePackProtocol();
Not
JSON varsayılan olarak etkindir. MessagePack eklemek hem JSON hem de MessagePack istemcileri için destek sağlar.
MessagePack'in verileri biçimlendirme biçimini özelleştirmek için seçenekleri AddMessagePackProtocol
yapılandırmak üzere bir temsilci alır. Bu temsilcide SerializerOptions
özelliği MessagePack serileştirme seçeneklerini yapılandırmak için kullanılır. Çözümleyicilerin nasıl çalıştığı hakkında daha fazla bilgi için MessagePack-CSharp sayfasındaki MessagePack kitaplığını ziyaret edin. Öznitelikler, nasıl işlenmeleri gerektiğini tanımlamak için serileştirmek istediğiniz nesnelerde kullanılabilir.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(new CustomResolver())
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Uyarı
CVE-2020-5234'in gözden geçirilmesini ve önerilen düzeltme eklerinin uygulanmasını kesinlikle öneririz. Örneğin, öğesini değiştirirken çağrısı.WithSecurity(MessagePackSecurity.UntrustedData)
.SerializerOptions
İstemcide MessagePack'i yapılandırma
Not
Desteklenen istemciler için JSON varsayılan olarak etkindir. İstemciler yalnızca tek bir protokolü destekleyebilir. MessagePack desteğinin eklenmesi, önceden yapılandırılmış protokollerin yerini alır.
.NET istemcisi
.NET İstemcisi'nde MessagePack'i etkinleştirmek için paketini yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
ve üzerinde çağrısında AddMessagePackProtocol
bulunur HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Not
Bu AddMessagePackProtocol
çağrı, sunucu gibi seçenekleri yapılandırmak için bir temsilci alır.
JavaScript istemcisi
JavaScript istemcisi için MessagePack desteği @microsoft/signalr-protocol-msgpack npm paketi tarafından sağlanır. Bir komut kabuğunda aşağıdaki komutu yürüterek paketi yükleyin:
npm install @microsoft/signalr-protocol-msgpack
npm paketini yükledikten sonra, modül bir JavaScript modül yükleyicisi aracılığıyla doğrudan kullanılabilir veya aşağıdaki dosyaya başvurarak tarayıcıya aktarılabilir:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Aşağıdaki gerekli javaScript dosyalarına aşağıda gösterilen sırayla başvurulmalıdır:
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
öğesine HubConnectionBuilder
eklemek.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
, istemciyi bir sunucuya bağlanırken MessagePack protokolunu kullanacak şekilde yapılandırıyor.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Şu anda JavaScript istemcisinde MessagePack protokolü için yapılandırma seçeneği yoktur.
Java istemcisi
Java ile MessagePack'i etkinleştirmek için paketi yükleyin com.microsoft.signalr.messagepack
. Gradle kullanırken build.gradle dosyasının dependencies
bölümüne aşağıdaki satırı ekleyin:
implementation 'com.microsoft.signalr.messagepack:signalr-messagepack:5.0.0'
Maven kullanırken, dosyanın öğesinin <dependencies>
pom.xml
içine aşağıdaki satırları ekleyin:
<dependency>
<groupId>com.microsoft.signalr.messagepack</groupId>
<artifactId>signalr</artifactId>
<version>5.0.0</version>
</dependency>
üzerinde HubConnectionBuilder
arayınwithHubProtocol(new MessagePackHubProtocol())
.
HubConnection messagePackConnection = HubConnectionBuilder.create("YOUR HUB URL HERE")
.withHubProtocol(new MessagePackHubProtocol())
.build();
MessagePack ile ilgili dikkat edilmesi gerekenler
MessagePack Hub Protokolü kullanılırken dikkat edilmesi gereken birkaç sorun vardır.
MessagePack büyük/küçük harfe duyarlıdır
MessagePack protokolü büyük/küçük harfe duyarlıdır. Örneğin, aşağıdaki C# sınıfını göz önünde bulundurun:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
JavaScript istemcisinden gönderirken, büyük/küçük harf kullanımının C# sınıfıyla tam olarak eşleşmesi gerektiğinden özellik adlarını kullanmanız PascalCased
gerekir. Örneğin:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Adların kullanılması camelCased
C# sınıfına düzgün bağlanmaz. MessagePack özelliği için farklı bir ad belirtmek üzere özniteliğini kullanarak Key
bu sorunu geçici olarak aşabilirsiniz. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın.
Seri durumdan çıkarılırken/seri durumdan çıkarılırken DateTime.Kind korunmuyor
MessagePack protokolü değerini kodlamak Kind
için bir DateTime
yol sağlamaz. Sonuç olarak, bir tarihi seri durumdan çıkarırken, aksi takdirde DateTime.Kind
DateTimeKind.Local
MessagePack Hub Protokolü saate dokunmaz ve olduğu gibi geçirmezse UTC biçimine dönüştürülür. Değerlerle DateTime
çalışıyorsanız, bunları göndermeden önce UTC'ye dönüştürmenizi öneririz. Bunları aldığınızda UTC'den yerel saate dönüştürün.
"Önceden" derleme ortamında MessagePack desteği
.NET istemcisi ve sunucusu tarafından kullanılan MessagePack-CSharp kitaplığı, serileştirmeyi iyileştirmek için kod oluşturmayı kullanır. Sonuç olarak, "zamanından önce" derleme kullanan ortamlarda (Xamarin iOS veya Unity gibi) varsayılan olarak desteklenmez. MessagePack'i bu ortamlarda seri hale getirici/seri durumdan çıkarıcı kodunu "önceden oluşturarak" kullanmak mümkündür. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın. Seri hale getiricileri önceden oluşturduktan sonra, öğesine geçirilen AddMessagePackProtocol
yapılandırma temsilcisini kullanarak bunları kaydedebilirsiniz:
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);
});
MessagePack'te tür denetimleri daha katıdır
JSON Hub Protokolü seri durumdan çıkarma sırasında tür dönüştürmeleri gerçekleştirir. Örneğin, gelen nesnenin bir sayı ({ foo: 42 }
) olan bir özellik değeri varsa, ancak .NET sınıfındaki özellik türündeyse string
, değer dönüştürülür. Ancak, MessagePack bu dönüştürmeyi gerçekleştirmez ve sunucu tarafı günlüklerinde (ve konsolunda) görülebilecek bir özel durum oluşturur:
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2937.
Java'da Karakterler ve Dizeler
Java istemcisinde nesneler tek char
karakterli String
nesneler olarak serileştirilir. Bu, C# ve JavaScript istemcisinin aksinedir ve bunları nesne olarak short
serileştirir. MessagePack belirtiminin kendisi nesneler için char
davranış tanımlamaz, bu nedenle bunların nasıl serileştirileceğini belirlemek kitaplık yazarına bağlıdır. Müşterilerimiz arasındaki davranış farkı, uygulamalarımız için kullandığımız kitaplıkların bir sonucudur.
Ek kaynaklar
Bu makalede, okuyucunun ASP.NET Core kullanmaya başlama başlığı altında ele alınan konulara aşina olduğu varsayılır SignalR.
MessagePack nedir?
MessagePack hızlı ve kompakt bir ikili serileştirme biçimidir. JSON ile karşılaştırıldığında daha küçük iletiler oluşturduğundan performans ve bant genişliği önemli olduğunda kullanışlıdır. Baytlar bir MessagePack ayrıştırıcısı üzerinden geçirilmediği sürece, ağ izlemelerine ve günlüklerine bakılırken ikili iletiler okunamaz. SignalR MessagePack biçimi için yerleşik desteğe sahiptir ve istemci ve sunucunun kullanması için API'ler sağlar.
Sunucuda MessagePack'i yapılandırma
Sunucuda MessagePack Hub Protokolü'ni etkinleştirmek için paketi uygulamanıza yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
. yönteminde Startup.ConfigureServices
, sunucuda MessagePack desteğini etkinleştirmek için çağrısına ekleyin AddMessagePackProtocol
AddSignalR
.
Not
JSON varsayılan olarak etkindir. MessagePack eklemek hem JSON hem de MessagePack istemcileri için destek sağlar.
services.AddSignalR()
.AddMessagePackProtocol();
MessagePack'in verilerinizi nasıl biçimlendireceğini özelleştirmek için seçenekleri AddMessagePackProtocol
yapılandırmak üzere bir temsilci alır. Bu temsilcide SerializerOptions
özelliği MessagePack serileştirme seçeneklerini yapılandırmak için kullanılabilir. Çözümleyicilerin nasıl çalıştığı hakkında daha fazla bilgi için MessagePack-CSharp sayfasındaki MessagePack kitaplığını ziyaret edin. Öznitelikler, nasıl işlenmeleri gerektiğini tanımlamak için serileştirmek istediğiniz nesnelerde kullanılabilir.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithResolver(new CustomResolver())
.WithSecurity(MessagePackSecurity.UntrustedData);
});
Uyarı
CVE-2020-5234'in gözden geçirilmesini ve önerilen düzeltme eklerinin uygulanmasını kesinlikle öneririz. Örneğin, öğesini değiştirirken çağrısı.WithSecurity(MessagePackSecurity.UntrustedData)
.SerializerOptions
İstemcide MessagePack'i yapılandırma
Not
Desteklenen istemciler için JSON varsayılan olarak etkindir. İstemciler yalnızca tek bir protokolü destekleyebilir. MessagePack desteğinin eklenmesi, önceden yapılandırılmış protokollerin yerini alır.
.NET istemcisi
.NET İstemcisi'nde MessagePack'i etkinleştirmek için paketini yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
ve üzerinde çağrısında AddMessagePackProtocol
bulunur HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Not
Bu AddMessagePackProtocol
çağrı, sunucu gibi seçenekleri yapılandırmak için bir temsilci alır.
JavaScript istemcisi
JavaScript istemcisi için MessagePack desteği @microsoft/signalr-protocol-msgpack npm paketi tarafından sağlanır. Bir komut kabuğunda aşağıdaki komutu yürüterek paketi yükleyin:
npm install @microsoft/signalr-protocol-msgpack
npm paketini yükledikten sonra, modül bir JavaScript modül yükleyicisi aracılığıyla doğrudan kullanılabilir veya aşağıdaki dosyaya başvurarak tarayıcıya aktarılabilir:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Tarayıcıda kitaplığa msgpack5
da başvurulmalıdır. <script>
Başvuru oluşturmak için etiket kullanın. Kitaplık node_modules\msgpack5\dist\msgpack5.js.
Not
öğesi kullanılırken <script>
sıra önemlidir. öncesinde msgpack5.js
başvurulursasignalr-protocol-msgpack.js
, MessagePack ile bağlanmaya çalışılırken bir hata oluşur. signalr.js
, öncesinde signalr-protocol-msgpack.js
de gereklidir.
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/msgpack5/msgpack5.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
öğesine HubConnectionBuilder
eklemek.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
, istemciyi bir sunucuya bağlanırken MessagePack protokolunu kullanacak şekilde yapılandıracaktır.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Not
Şu anda JavaScript istemcisinde MessagePack protokolü için yapılandırma seçeneği yoktur.
Java istemcisi
Java ile MessagePack'i etkinleştirmek için paketi yükleyin com.microsoft.signalr.messagepack
. Gradle kullanırken build.gradle dosyasının dependencies
bölümüne aşağıdaki satırı ekleyin:
implementation 'com.microsoft.signalr.messagepack:signalr-messagepack:5.0.0'
Maven kullanırken, dosyanın öğesinin <dependencies>
pom.xml
içine aşağıdaki satırları ekleyin:
<dependency>
<groupId>com.microsoft.signalr.messagepack</groupId>
<artifactId>signalr</artifactId>
<version>5.0.0</version>
</dependency>
üzerinde HubConnectionBuilder
arayınwithHubProtocol(new MessagePackHubProtocol())
.
HubConnection messagePackConnection = HubConnectionBuilder.create("YOUR HUB URL HERE")
.withHubProtocol(new MessagePackHubProtocol())
.build();
MessagePack ile ilgili dikkat edilmesi gerekenler
MessagePack Hub Protokolü kullanılırken dikkat edilmesi gereken birkaç sorun vardır.
MessagePack büyük/küçük harfe duyarlıdır
MessagePack protokolü büyük/küçük harfe duyarlıdır. Örneğin, aşağıdaki C# sınıfını göz önünde bulundurun:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
JavaScript istemcisinden gönderirken, büyük/küçük harf kullanımının C# sınıfıyla tam olarak eşleşmesi gerektiğinden özellik adlarını kullanmanız PascalCased
gerekir. Örneğin:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Adların kullanılması camelCased
C# sınıfına düzgün bağlanmaz. MessagePack özelliği için farklı bir ad belirtmek üzere özniteliğini kullanarak Key
bu sorunu geçici olarak aşabilirsiniz. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın.
Seri durumdan çıkarılırken/seri durumdan çıkarılırken DateTime.Kind korunmuyor
MessagePack protokolü değerini kodlamak Kind
için bir DateTime
yol sağlamaz. Sonuç olarak, bir tarihi seri durumdan çıkarırken, aksi takdirde DateTime.Kind
DateTimeKind.Local
MessagePack Hub Protokolü saate dokunmaz ve olduğu gibi geçirmezse UTC biçimine dönüştürülür. Değerlerle DateTime
çalışıyorsanız, bunları göndermeden önce UTC'ye dönüştürmenizi öneririz. Bunları aldığınızda UTC'den yerel saate dönüştürün.
DateTime.MinValue, JavaScript'te MessagePack tarafından desteklenmiyor
JavaScript istemcisi tarafından SignalR kullanılan msgpack5 kitaplığı MessagePack'teki türü desteklemeztimestamp96
. Bu tür, çok büyük tarih değerlerini (geçmişte çok erken veya gelecekte çok uzak) kodlamak için kullanılır. değeri, bir timestamp96
değerde DateTime.MinValue
kodlanması gereken değeridirJanuary 1, 0001
. Bu nedenle JavaScript istemcisine gönderme DateTime.MinValue
desteklenmez. DateTime.MinValue
JavaScript istemcisi tarafından alındığında aşağıdaki hata oluşur:
Uncaught Error: unable to find ext type 255 at decoder.js:427
Genellikle bir DateTime.MinValue
"eksik" veya null
değeri kodlamak için kullanılır. MessagePack'te bu değeri kodlamanız gerekiyorsa, null atanabilir DateTime
bir değer (DateTime?
) kullanın veya tarihin mevcut olup olmadığını belirten ayrı bool
bir değeri kodlayın.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2228.
"Önceden" derleme ortamında MessagePack desteği
.NET istemcisi ve sunucusu tarafından kullanılan MessagePack-CSharp kitaplığı, serileştirmeyi iyileştirmek için kod oluşturmayı kullanır. Sonuç olarak, "zamanından önce" derleme kullanan ortamlarda (Xamarin iOS veya Unity gibi) varsayılan olarak desteklenmez. MessagePack'i bu ortamlarda seri hale getirici/seri durumdan çıkarıcı kodunu "önceden oluşturarak" kullanmak mümkündür. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın. Seri hale getiricileri önceden oluşturduktan sonra, öğesine geçirilen AddMessagePackProtocol
yapılandırma temsilcisini kullanarak bunları kaydedebilirsiniz:
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);
});
MessagePack'te tür denetimleri daha katıdır
JSON Hub Protokolü seri durumdan çıkarma sırasında tür dönüştürmeleri gerçekleştirir. Örneğin, gelen nesnenin bir sayı ({ foo: 42 }
) olan bir özellik değeri varsa, ancak .NET sınıfındaki özellik türündeyse string
, değer dönüştürülür. Ancak, MessagePack bu dönüştürmeyi gerçekleştirmez ve sunucu tarafı günlüklerinde (ve konsolunda) görülebilecek bir özel durum oluşturur:
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2937.
Java'da Karakterler ve Dizeler
Java istemcisinde nesneler tek char
karakterli String
nesneler olarak serileştirilir. Bu, C# ve JavaScript istemcisinin aksinedir ve bunları nesne olarak short
serileştirir. MessagePack belirtiminin kendisi nesneler için char
davranış tanımlamaz, bu nedenle bunların nasıl serileştirileceğini belirlemek kitaplık yazarına bağlıdır. Müşterilerimiz arasındaki davranış farkı, uygulamalarımız için kullandığımız kitaplıkların bir sonucudur.
Ek kaynaklar
Bu makalede, okuyucunun ASP.NET Core kullanmaya başlama başlığı altında ele alınan konulara aşina olduğu varsayılır SignalR.
MessagePack nedir?
MessagePack hızlı ve kompakt bir ikili serileştirme biçimidir. JSON ile karşılaştırıldığında daha küçük iletiler oluşturduğundan performans ve bant genişliği önemli olduğunda kullanışlıdır. Baytlar bir MessagePack ayrıştırıcısı üzerinden geçirilmediği sürece, ağ izlemelerine ve günlüklerine bakılırken ikili iletiler okunamaz. SignalR , MessagePack biçimi için yerleşik desteğe sahiptir ve istemci ve sunucunun kullanması için API'ler sağlar.
Sunucuda MessagePack'i yapılandırma
Sunucuda MessagePack Hub Protokolü'ni etkinleştirmek için paketi uygulamanıza yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
. yönteminde Startup.ConfigureServices
, sunucuda MessagePack desteğini etkinleştirmek için çağrısına ekleyin AddMessagePackProtocol
AddSignalR
.
Not
JSON varsayılan olarak etkindir. MessagePack eklemek hem JSON hem de MessagePack istemcileri için destek sağlar.
services.AddSignalR()
.AddMessagePackProtocol();
MessagePack'in verilerinizi nasıl biçimlendireceğini özelleştirmek için seçenekleri AddMessagePackProtocol
yapılandırmak üzere bir temsilci alır. Bu temsilcide FormatterResolvers
özelliği MessagePack serileştirme seçeneklerini yapılandırmak için kullanılabilir. Çözümleyicilerin nasıl çalıştığı hakkında daha fazla bilgi için MessagePack-CSharp sayfasındaki MessagePack kitaplığını ziyaret edin. Öznitelikler, nasıl işlenmeleri gerektiğini tanımlamak için serileştirmek istediğiniz nesnelerde kullanılabilir.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.StandardResolver.Instance
};
});
Uyarı
CVE-2020-5234'in gözden geçirilmesini ve önerilen düzeltme eklerinin uygulanmasını kesinlikle öneririz. Örneğin, statik özelliği olarak MessagePackSecurity.UntrustedData
ayarlayınMessagePackSecurity.Active
. ayarının MessagePackSecurity.Active
ayarlanması için MessagePack'in 1.9.x sürümünün el ile yüklenmesi gerekir. 1.9.x'i yüklemek MessagePack
, sürümün kullandığı sürümü SignalR yükselter. MessagePack
sürüm 2.x, hataya neden olan değişiklikler yaptı ve 3.1 ve önceki sürümlerle SignalR uyumlu değil. MessagePackSecurity.Active
olarak ayarlı MessagePackSecurity.UntrustedData
olmadığında, kötü amaçlı bir istemci hizmet reddine neden olabilir. Program.Main
içinde, aşağıdaki kodda gösterildiği gibi ayarlayınMessagePackSecurity.Active
:
using MessagePack;
public static void Main(string[] args)
{
MessagePackSecurity.Active = MessagePackSecurity.UntrustedData;
CreateHostBuilder(args).Build().Run();
}
İstemcide MessagePack'i yapılandırma
Not
Desteklenen istemciler için JSON varsayılan olarak etkindir. İstemciler yalnızca tek bir protokolü destekleyebilir. MessagePack desteğinin eklenmesi, önceden yapılandırılmış protokollerin yerini alır.
.NET istemcisi
.NET İstemcisi'nde MessagePack'i etkinleştirmek için paketini yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
ve üzerinde çağrısında AddMessagePackProtocol
bulunur HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Not
Bu AddMessagePackProtocol
çağrı, sunucu gibi seçenekleri yapılandırmak için bir temsilci alır.
JavaScript istemcisi
JavaScript istemcisi için MessagePack desteği @microsoft/signalr-protocol-msgpack npm paketi tarafından sağlanır. Bir komut kabuğunda aşağıdaki komutu yürüterek paketi yükleyin:
npm install @microsoft/signalr-protocol-msgpack
npm paketini yükledikten sonra, modül bir JavaScript modül yükleyicisi aracılığıyla doğrudan kullanılabilir veya aşağıdaki dosyaya başvurarak tarayıcıya aktarılabilir:
node_modules\@microsoft\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Tarayıcıda kitaplığa msgpack5
da başvurulmalıdır. <script>
Başvuru oluşturmak için etiket kullanın. Kitaplık node_modules\msgpack5\dist\msgpack5.js.
Not
öğesi kullanılırken <script>
sıra önemlidir. öncesinde msgpack5.js
başvurulursasignalr-protocol-msgpack.js
, MessagePack ile bağlanmaya çalışılırken bir hata oluşur. signalr.js
, öncesinde signalr-protocol-msgpack.js
de gereklidir.
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/msgpack5/msgpack5.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
öğesine HubConnectionBuilder
eklemek.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
, istemciyi bir sunucuya bağlanırken MessagePack protokolunu kullanacak şekilde yapılandıracaktır.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Not
Şu anda JavaScript istemcisinde MessagePack protokolü için yapılandırma seçeneği yoktur.
MessagePack ile ilgili dikkat edilmesi gerekenler
MessagePack Hub Protokolü kullanılırken dikkat edilmesi gereken birkaç sorun vardır.
MessagePack büyük/küçük harfe duyarlıdır
MessagePack protokolü büyük/küçük harfe duyarlıdır. Örneğin, aşağıdaki C# sınıfını göz önünde bulundurun:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
JavaScript istemcisinden gönderirken, büyük/küçük harf kullanımının C# sınıfıyla tam olarak eşleşmesi gerektiğinden özellik adlarını kullanmanız PascalCased
gerekir. Örneğin:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Adların kullanılması camelCased
C# sınıfına düzgün bağlanmaz. MessagePack özelliği için farklı bir ad belirtmek üzere özniteliğini kullanarak Key
bu sorunu geçici olarak aşabilirsiniz. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın.
Seri durumdan çıkarılırken/seri durumdan çıkarılırken DateTime.Kind korunmuyor
MessagePack protokolü değerini kodlamak Kind
için bir DateTime
yol sağlamaz. Sonuç olarak, bir tarihi seri durumdan çıkarırken MessagePack Hub Protokolü gelen tarihin UTC biçiminde olduğunu varsayar. Yerel saat değerleriyle DateTime
çalışıyorsanız, bunları göndermeden önce UTC'ye dönüştürmenizi öneririz. Bunları aldığınızda UTC'den yerel saate dönüştürün.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2632.
DateTime.MinValue, JavaScript'te MessagePack tarafından desteklenmiyor
JavaScript istemcisi tarafından SignalR kullanılan msgpack5 kitaplığı MessagePack'teki türü desteklemeztimestamp96
. Bu tür, çok büyük tarih değerlerini (geçmişte çok erken veya gelecekte çok uzak) kodlamak için kullanılır. değeri, bir timestamp96
değerde DateTime.MinValue
kodlanması gereken değeridirJanuary 1, 0001
. Bu nedenle JavaScript istemcisine gönderme DateTime.MinValue
desteklenmez. DateTime.MinValue
JavaScript istemcisi tarafından alındığında aşağıdaki hata oluşur:
Uncaught Error: unable to find ext type 255 at decoder.js:427
Genellikle bir DateTime.MinValue
"eksik" veya null
değeri kodlamak için kullanılır. MessagePack'te bu değeri kodlamanız gerekiyorsa, null atanabilir DateTime
bir değer (DateTime?
) kullanın veya tarihin mevcut olup olmadığını belirten ayrı bool
bir değeri kodlayın.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2228.
"Önceden" derleme ortamında MessagePack desteği
.NET istemcisi ve sunucusu tarafından kullanılan MessagePack-CSharp kitaplığı, serileştirmeyi iyileştirmek için kod oluşturmayı kullanır. Sonuç olarak, "zamanından önce" derleme kullanan ortamlarda (Xamarin iOS veya Unity gibi) varsayılan olarak desteklenmez. MessagePack'i bu ortamlarda seri hale getirici/seri durumdan çıkarıcı kodunu "önceden oluşturarak" kullanmak mümkündür. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın. Seri hale getiricileri önceden oluşturduktan sonra, öğesine geçirilen AddMessagePackProtocol
yapılandırma temsilcisini kullanarak bunları kaydedebilirsiniz:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
};
});
MessagePack'te tür denetimleri daha katıdır
JSON Hub Protokolü seri durumdan çıkarma sırasında tür dönüştürmeleri gerçekleştirir. Örneğin, gelen nesnenin bir sayı ({ foo: 42 }
) olan bir özellik değeri varsa, ancak .NET sınıfındaki özellik türündeyse string
, değer dönüştürülür. Ancak, MessagePack bu dönüştürmeyi gerçekleştirmez ve sunucu tarafı günlüklerinde (ve konsolunda) görülebilecek bir özel durum oluşturur:
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2937.
Ek kaynaklar
Bu makalede, okuyucunun ASP.NET Core kullanmaya başlama başlığı altında ele alınan konulara aşina olduğu varsayılır SignalR.
MessagePack nedir?
MessagePack hızlı ve kompakt bir ikili serileştirme biçimidir. JSON ile karşılaştırıldığında daha küçük iletiler oluşturduğundan performans ve bant genişliği önemli olduğunda kullanışlıdır. Baytlar bir MessagePack ayrıştırıcısı üzerinden geçirilmediği sürece, ağ izlemelerine ve günlüklerine bakılırken ikili iletiler okunamaz. SignalR , MessagePack biçimi için yerleşik desteğe sahiptir ve istemci ve sunucunun kullanması için API'ler sağlar.
Sunucuda MessagePack'i yapılandırma
Sunucuda MessagePack Hub Protokolü'ni etkinleştirmek için paketi uygulamanıza yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
. yönteminde Startup.ConfigureServices
, sunucuda MessagePack desteğini etkinleştirmek için çağrısına ekleyin AddMessagePackProtocol
AddSignalR
.
Not
JSON varsayılan olarak etkindir. MessagePack eklemek hem JSON hem de MessagePack istemcileri için destek sağlar.
services.AddSignalR()
.AddMessagePackProtocol();
MessagePack'in verilerinizi nasıl biçimlendireceğini özelleştirmek için seçenekleri AddMessagePackProtocol
yapılandırmak üzere bir temsilci alır. Bu temsilcide FormatterResolvers
özelliği MessagePack serileştirme seçeneklerini yapılandırmak için kullanılabilir. Çözümleyicilerin nasıl çalıştığı hakkında daha fazla bilgi için MessagePack-CSharp sayfasındaki MessagePack kitaplığını ziyaret edin. Öznitelikler, nasıl işlenmeleri gerektiğini tanımlamak için serileştirmek istediğiniz nesnelerde kullanılabilir.
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.StandardResolver.Instance
};
});
Uyarı
CVE-2020-5234'in gözden geçirilmesini ve önerilen düzeltme eklerinin uygulanmasını kesinlikle öneririz. Örneğin, statik özelliği olarak MessagePackSecurity.UntrustedData
ayarlayınMessagePackSecurity.Active
. ayarının MessagePackSecurity.Active
ayarlanması için MessagePack'in 1.9.x sürümünün el ile yüklenmesi gerekir. 1.9.x'i yüklemek MessagePack
, sürümün kullandığı sürümü SignalR yükselter. olarak ayarlanmadığında MessagePackSecurity.Active
MessagePackSecurity.UntrustedData
kötü amaçlı bir istemci hizmet reddine neden olabilir. Program.Main
içinde, aşağıdaki kodda gösterildiği gibi ayarlayınMessagePackSecurity.Active
:
using MessagePack;
public static void Main(string[] args)
{
MessagePackSecurity.Active = MessagePackSecurity.UntrustedData;
CreateHostBuilder(args).Build().Run();
}
İstemcide MessagePack'i yapılandırma
Not
Desteklenen istemciler için JSON varsayılan olarak etkindir. İstemciler yalnızca tek bir protokolü destekleyebilir. MessagePack desteğinin eklenmesi, önceden yapılandırılmış protokollerin yerini alır.
.NET istemcisi
.NET İstemcisi'nde MessagePack'i etkinleştirmek için paketini yükleyin Microsoft.AspNetCore.SignalR.Protocols.MessagePack
ve üzerinde çağrısında AddMessagePackProtocol
bulunur HubConnectionBuilder
.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
var hubConnection = new HubConnectionBuilder()
.WithUrl("/chathub")
.AddMessagePackProtocol()
.Build();
Not
Bu AddMessagePackProtocol
çağrı, sunucu gibi seçenekleri yapılandırmak için bir temsilci alır.
JavaScript istemcisi
JavaScript istemcisi için MessagePack desteği @aspnet/signalr-protocol-msgpack npm paketi tarafından sağlanır. Bir komut kabuğunda aşağıdaki komutu yürüterek paketi yükleyin:
npm install @aspnet/signalr-protocol-msgpack
npm paketini yükledikten sonra, modül bir JavaScript modül yükleyicisi aracılığıyla doğrudan kullanılabilir veya aşağıdaki dosyaya başvurarak tarayıcıya aktarılabilir:
node_modules\@aspnet\signalr-protocol-msgpack\dist\browser\signalr-protocol-msgpack.js
Tarayıcıda kitaplığa msgpack5
da başvurulmalıdır. <script>
Başvuru oluşturmak için etiket kullanın. Kitaplık node_modules\msgpack5\dist\msgpack5.js.
Not
öğesi kullanılırken <script>
sıra önemlidir. öncesinde msgpack5.js
başvurulursasignalr-protocol-msgpack.js
, MessagePack ile bağlanmaya çalışılırken bir hata oluşur. signalr.js
, öncesinde signalr-protocol-msgpack.js
de gereklidir.
<script src="~/lib/signalr/signalr.js"></script>
<script src="~/lib/msgpack5/msgpack5.js"></script>
<script src="~/lib/signalr/signalr-protocol-msgpack.js"></script>
öğesine HubConnectionBuilder
eklemek.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
, istemciyi bir sunucuya bağlanırken MessagePack protokolunu kullanacak şekilde yapılandıracaktır.
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol())
.build();
Not
Şu anda JavaScript istemcisinde MessagePack protokolü için yapılandırma seçeneği yoktur.
MessagePack ile ilgili dikkat edilmesi gerekenler
MessagePack Hub Protokolü kullanılırken dikkat edilmesi gereken birkaç sorun vardır.
MessagePack büyük/küçük harfe duyarlıdır
MessagePack protokolü büyük/küçük harfe duyarlıdır. Örneğin, aşağıdaki C# sınıfını göz önünde bulundurun:
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
JavaScript istemcisinden gönderirken, büyük/küçük harf kullanımının C# sınıfıyla tam olarak eşleşmesi gerektiğinden özellik adlarını kullanmanız PascalCased
gerekir. Örneğin:
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
Adların kullanılması camelCased
C# sınıfına düzgün bağlanmaz. MessagePack özelliği için farklı bir ad belirtmek üzere özniteliğini kullanarak Key
bu sorunu geçici olarak aşabilirsiniz. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın.
Seri durumdan çıkarılırken/seri durumdan çıkarılırken DateTime.Kind korunmuyor
MessagePack protokolü değerini kodlamak Kind
için bir DateTime
yol sağlamaz. Sonuç olarak, bir tarihi seri durumdan çıkarırken MessagePack Hub Protokolü gelen tarihin UTC biçiminde olduğunu varsayar. Yerel saat değerleriyle DateTime
çalışıyorsanız, bunları göndermeden önce UTC'ye dönüştürmenizi öneririz. Bunları aldığınızda UTC'den yerel saate dönüştürün.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2632.
DateTime.MinValue, JavaScript'te MessagePack tarafından desteklenmiyor
JavaScript istemcisi tarafından SignalR kullanılan msgpack5 kitaplığı MessagePack'teki türü desteklemeztimestamp96
. Bu tür, çok büyük tarih değerlerini (geçmişte çok erken veya gelecekte çok uzak) kodlamak için kullanılır. değeri, bir timestamp96
değerde DateTime.MinValue
kodlanması gereken değerdirJanuary 1, 0001
. Bu nedenle JavaScript istemcisine gönderme DateTime.MinValue
desteklenmez. DateTime.MinValue
JavaScript istemcisi tarafından alındığında aşağıdaki hata oluşur:
Uncaught Error: unable to find ext type 255 at decoder.js:427
Genellikle bir DateTime.MinValue
"eksik" veya null
değeri kodlamak için kullanılır. MessagePack'te bu değeri kodlamanız gerekiyorsa, null atanabilir DateTime
bir değer (DateTime?
) kullanın veya tarihin mevcut olup olmadığını belirten ayrı bool
bir değeri kodlayın.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2228.
"Önceden" derleme ortamında MessagePack desteği
.NET istemcisi ve sunucusu tarafından kullanılan MessagePack-CSharp kitaplığı, serileştirmeyi iyileştirmek için kod oluşturmayı kullanır. Sonuç olarak, "zamanından önce" derleme kullanan ortamlarda (Xamarin iOS veya Unity gibi) varsayılan olarak desteklenmez. MessagePack'i bu ortamlarda seri hale getirici/seri durumdan çıkarıcı kodunu "önceden oluşturarak" kullanmak mümkündür. Daha fazla bilgi için MessagePack-CSharp belgelerine bakın. Seri hale getiricileri önceden oluşturduktan sonra, öğesine geçirilen AddMessagePackProtocol
yapılandırma temsilcisini kullanarak bunları kaydedebilirsiniz:
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
};
});
MessagePack'te tür denetimleri daha katıdır
JSON Hub Protokolü seri durumdan çıkarma sırasında tür dönüştürmeleri gerçekleştirir. Örneğin, gelen nesnenin bir sayı ({ foo: 42 }
) olan bir özellik değeri varsa, ancak .NET sınıfındaki özellik türündeyse string
, değer dönüştürülür. Ancak, MessagePack bu dönüştürmeyi gerçekleştirmez ve sunucu tarafı günlüklerinde (ve konsolunda) görülebilecek bir özel durum oluşturur:
InvalidDataException: Error binding arguments. Make sure that the types of the provided values match the types of the hub method being invoked.
Bu sınırlama hakkında daha fazla bilgi için bkz. GitHub sorunu aspnet/SignalR#2937.
Ek kaynaklar
ASP.NET Core