Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add section on SignalR MessagePack "known issues" #11170

Merged
merged 4 commits into from
Mar 5, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions aspnetcore/signalr/messagepackhubprotocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,64 @@ const connection = new signalR.HubConnectionBuilder()
> [!NOTE]
> At this time, there are no configuration options for the MessagePack protocol on the JavaScript client.

## MessagePack Quirks
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure "quirks" is the right name here... very open to suggestions. I hestitate to use "Known Issues" because that (to me) implies that we're going to work on fixing them, which we aren't. I started with "Differences between MessagePack and JSON serialization" but some of these aren't exactly "differences" between JSON and MessagePack, they're just notable things for MessagePack (AOT support, for example didn't feel like a "difference"... though it kind of is... 🤷‍♂️).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "quirks" describes it well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use sentence casing for headings. For example, "MessagePack quirks".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, wasn't sure if there's a translation concern around using a word like "quirks". I'll update the casing.


There are a few unique issues to be aware of when using the MessagePack Hub Protocol.
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

### MessagePack is case-sensitive

The MessagePack protocol is case-sensitive. For example, consider the following C# class:

```csharp
public class ChatMessage
{
public string Sender { get; }
public string Message { get; }
}
```

When sending from the JavaScript client, you must use `PascalCased` property names, since the casing must match the C# class exactly. For example:

```javascript
connection.invoke("SomeMethod", { Sender: "Sally", Message: "Hello!" });
```

Using `camelCased` names will not properly bind to the C# class. You can work around this by using the `Key` attribute to specify a different name for the MessagePack property. See [the MessagePack-CSharp documentation](https://github.com/neuecc/MessagePack-CSharp#object-serialization) for more information.
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

### DateTime.MinValue is not supported by MessagePack in JavaScript

The [msgpack5](https://github.com/mcollina/msgpack5) library used by the SignalR JavaScript client does not support the `timestamp96` type in MessagePack. This type is used to encode very large date values (either very early in the past or very far in the future). The value of `DateTime.MinValue` is `January 1, 0001` which must be encoded in a `timestamp96` value. Because of this, sending `DateTime.MinValue` to a JavaScript client is not supported. Usually, `DateTime.MinValue` is used to encode a "missing" or `null` value. If you need to encode that value in MessagePack, use a nullable `DateTime` value (`DateTime?`) or encode a separate `bool` value indicating if the date is present.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of this, sending DateTime.MinValue to a JavaScript client is not supported.

If I tried to send DateTime.MinValue to the JS client with MessagePack, what would happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception shows up in the JS console:

Uncaught Error: unable to find ext type 255 at decoder.js:427
at h (decoder.js:427)
at l (decoder.js:263)
at d (decoder.js:358)
at l (decoder.js:243)
at u (decoder.js:335)
at l (decoder.js:285)
at u (decoder.js:335)
at l (decoder.js:285)
at u (decoder.js:335)
at l (decoder.js:285)

See aspnet/SignalR#2228

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could include that text in the doc for google-fu

analogrelay marked this conversation as resolved.
Show resolved Hide resolved

See [aspnet/SignalR#2228](https://github.com/aspnet/SignalR/issues/2228) for more information on this limitation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it recommended to link to GitHub issues for complex topics? Maybe the prose should mention this is a GitHub issue incase some peopled don't recognize the "aspnet/SignalR#2228" GitHub link syntax.

We should probably make sure the issue is locked before linking to it in docs, but it doesn't matter in this particular case, since aspnet/SignalR is archived.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm not sure either. I'm happy to remove it but I thought it might be worth including the link to the issue for more context. Agreed that we can make it clearer that it's an issue link.

analogrelay marked this conversation as resolved.
Show resolved Hide resolved

### MessagePack support in "ahead-of-time" compilation environment

The [MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp) library used by the .NET Client and Server uses code generation to optimize serialization. As a result, it is not supported by default on environmment that use "ahead-of-time" compilation (such as Xamarin iOS or Unity). It is possible to use MessagePack in these environments by "pre-generating" the serializer/deserializer code. For more information see [the MessagePack-CSharp documentation](https://github.com/neuecc/MessagePack-CSharp#pre-code-generationunityxamarin-supports). Once you have pre-generated the serializers, you can register them using the configuration delegate passed to `AddMessagePackProtocol`:
analogrelay marked this conversation as resolved.
Show resolved Hide resolved
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

```csharp
services.AddSignalR()
.AddMessagePackProtocol(options =>
{
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
};
});
```

### Type checks are more strict in MessagePack

The JSON Hub Protocol will perform type conversions during deserialization. For example, if the incoming object has an property value that is a number (`{ foo: 42 }`) but the property on the .NET class is of type `string`, the value will be converted. However, MessagePack does not perform this conversion, and will throw an `InvalidDataException` instead.
analogrelay marked this conversation as resolved.
Show resolved Hide resolved
analogrelay marked this conversation as resolved.
Show resolved Hide resolved
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

See [aspnet/SignalR#2937](https://github.com/aspnet/SignalR/issues/2937) for more information on this limitation.
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

### DateTime.Kind is not preserved when serializing/deserializing
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

The MessagePack protocol does not provide a way to encode the `Kind` value of a `DateTime`. As a result, when deserializing a date, the MessagePack Hub Protocol assumes the incoming date is in UTC format. If you are working with `DateTime` values in local time, we recommend converting to UTC before sending them, and convert them from UTC to local time when you receive them.
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

See [aspnet/SignalR#2632](https://github.com/aspnet/SignalR/issues/2632) for more information on this limitation.
analogrelay marked this conversation as resolved.
Show resolved Hide resolved

## Related resources

* [Get Started](xref:tutorials/signalr)
Expand Down