Skip to content

Commit da42072

Browse files
committed
[ECO-4567] Implemented msgpack support
- Updated IMPLEMENTATION_MSGPACK_FROM_NEWTONSOFT plan - Accordingly added msgpack annotations for relevant models - Created separate project for generating msgpack serializers pre-compile time
1 parent b7b7995 commit da42072

21 files changed

+1116
-99
lines changed

IMPLEMENTATION_MSGPACK_FROM_NEWTONSOFT.md

Lines changed: 231 additions & 94 deletions
Large diffs are not rendered by default.

IMPL_MSGPACK.md

Lines changed: 404 additions & 0 deletions
Large diffs are not rendered by default.

src/IO.Ably.NETStandard20/IO.Ably.NETStandard20.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,7 @@
7272
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
7373
</PropertyGroup>
7474

75+
<!-- Import MsgPack serializer generation targets -->
76+
<Import Project="..\IO.Ably.Shared.MsgPack\IO.Ably.Shared.MsgPack.targets" Condition="Exists('..\IO.Ably.Shared.MsgPack\IO.Ably.Shared.MsgPack.targets')" />
77+
7578
</Project>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using IO.Ably.Types;
2+
using MsgPack;
3+
using MsgPack.Serialization;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace IO.Ably.CustomSerialisers
7+
{
8+
#pragma warning disable SA1600 // Elements should be documented
9+
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
10+
public class MessageExtrasMessagePackSerializer : MessagePackSerializer<MessageExtras>
11+
{
12+
public MessageExtrasMessagePackSerializer(SerializationContext ownerContext)
13+
: base(ownerContext)
14+
{
15+
}
16+
17+
protected override void PackToCore(Packer packer, MessageExtras objectTree)
18+
{
19+
if (objectTree == null)
20+
{
21+
packer.PackNull();
22+
return;
23+
}
24+
25+
var json = objectTree.ToJson();
26+
if (json == null)
27+
{
28+
packer.PackNull();
29+
}
30+
else
31+
{
32+
// Serialize as JSON string for compatibility
33+
packer.Pack(json.ToString(Newtonsoft.Json.Formatting.None));
34+
}
35+
}
36+
37+
protected override MessageExtras UnpackFromCore(Unpacker unpacker)
38+
{
39+
if (unpacker.LastReadData.IsNil)
40+
{
41+
return null;
42+
}
43+
44+
var jsonString = unpacker.LastReadData.AsString();
45+
if (string.IsNullOrEmpty(jsonString))
46+
{
47+
return null;
48+
}
49+
50+
var jToken = JToken.Parse(jsonString);
51+
return MessageExtras.From(jToken);
52+
}
53+
}
54+
#pragma warning restore SA1600 // Elements should be documented
55+
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
56+
}

src/IO.Ably.Shared.MsgPack/IO.Ably.Shared.MsgPack.projitems

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<ItemGroup>
1212
<Compile Include="$(MSBuildThisFileDirectory)CustomSerialisers\CapabilityMessagePackSerializer.cs" />
1313
<Compile Include="$(MSBuildThisFileDirectory)CustomSerialisers\DateTimeOffsetMessagePackSerializer.cs" />
14+
<Compile Include="$(MSBuildThisFileDirectory)CustomSerialisers\MessageExtrasMessagePackSerializer.cs" />
1415
<Compile Include="$(MSBuildThisFileDirectory)CustomSerialisers\GeneratedSerializers\IO_Ably_Auth_TokenDetailsSerializer.cs" />
1516
<Compile Include="$(MSBuildThisFileDirectory)CustomSerialisers\GeneratedSerializers\IO_Ably_CapabilitySerializer.cs" />
1617
<Compile Include="$(MSBuildThisFileDirectory)CustomSerialisers\GeneratedSerializers\IO_Ably_ConnectionDetailsMessageSerializer.cs" />
@@ -33,4 +34,4 @@
3334
<Compile Include="$(MSBuildThisFileDirectory)CustomSerialisers\TimespanMessagePackSerializer.cs" />
3435
<Compile Include="$(MSBuildThisFileDirectory)MsgPackHelper.cs" />
3536
</ItemGroup>
36-
</Project>
37+
</Project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
4+
<PropertyGroup>
5+
<MsgPackGeneratorProject>$(MSBuildThisFileDirectory)..\..\tools\MsgPackSerializerGenerator\MsgPackSerializerGenerator.csproj</MsgPackGeneratorProject>
6+
<MsgPackOutputDirectory>$(MSBuildThisFileDirectory)CustomSerialisers\GeneratedSerializers</MsgPackOutputDirectory>
7+
</PropertyGroup>
8+
9+
<!-- Generate MsgPack serializers before compilation -->
10+
<Target Name="GenerateMsgPackSerializers" BeforeTargets="CoreCompile" Condition="'$(DesignTimeBuild)' != 'true' AND '$(BuildingProject)' == 'true'">
11+
<Message Text="Generating MsgPack serializers..." Importance="high" />
12+
13+
<!-- Build the generator tool first -->
14+
<MSBuild Projects="$(MsgPackGeneratorProject)" Targets="Build" Properties="Configuration=$(Configuration)" />
15+
16+
<!-- Run the generator tool -->
17+
<Exec Command="dotnet &quot;$(MSBuildThisFileDirectory)..\..\tools\MsgPackSerializerGenerator\bin\$(Configuration)\net6.0\MsgPackSerializerGenerator.dll&quot; &quot;$(MsgPackOutputDirectory)&quot;"
18+
WorkingDirectory="$(MSBuildThisFileDirectory)" />
19+
20+
<Message Text="MsgPack serializers generated successfully" Importance="high" />
21+
</Target>
22+
23+
<!-- Clean generated files -->
24+
<Target Name="CleanMsgPackSerializers" BeforeTargets="CoreClean">
25+
<ItemGroup>
26+
<GeneratedSerializers Include="$(MsgPackOutputDirectory)\*.cs" />
27+
</ItemGroup>
28+
<Delete Files="@(GeneratedSerializers)" />
29+
</Target>
30+
31+
<!-- Include generated files in compilation -->
32+
<ItemGroup>
33+
<Compile Include="$(MsgPackOutputDirectory)\*.cs" />
34+
</ItemGroup>
35+
36+
</Project>

src/IO.Ably.Shared.MsgPack/MsgPackHelper.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ private static SerializationContext GetContext()
2020
var context = new SerializationContext() { SerializationMethod = SerializationMethod.Map };
2121
context.Serializers.Register(new DateTimeOffsetMessagePackSerializer(context));
2222
context.Serializers.Register(new TimespanMessagePackSerializer(context));
23+
context.Serializers.Register(new MessageExtrasMessagePackSerializer(context));
2324
context.Serializers.Register(new IO_Ably_CapabilitySerializer(context));
2425
context.Serializers.Register(new IO_Ably_TokenRequestSerializer(context));
2526
context.Serializers.Register(new IO_Ably_Auth_TokenDetailsSerializer(context));

src/IO.Ably.Shared/Push/DeviceDetails.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,89 @@
1-
using Newtonsoft.Json;
1+
using MsgPack.Serialization;
2+
using Newtonsoft.Json;
23
using Newtonsoft.Json.Linq;
34

45
namespace IO.Ably.Push
56
{
67
/// <summary>
78
/// Class representing a Device registered for Ably push notifications.
89
/// </summary>
10+
[MessagePackObject]
911
public class DeviceDetails
1012
{
1113
/// <summary>
1214
/// Device Id.
1315
/// </summary>
16+
[Key(0)]
1417
[JsonProperty("id")]
1518
public string Id { get; set; }
1619

1720
/// <summary>
1821
/// Device platform. One of 'android', 'ios' or 'browser').
1922
/// </summary>
23+
[Key(1)]
2024
[JsonProperty("platform")]
2125
public string Platform { get; set; }
2226

2327
/// <summary>
2428
/// Device form factor. One of 'phone', 'tablet', 'desktop', 'tv', 'watch', 'car' or 'embedded'.
2529
/// </summary>
30+
[Key(2)]
2631
[JsonProperty("formFactor")]
2732
public string FormFactor { get; set; }
2833

2934
/// <summary>
3035
/// Device ClientId which is associated with the push registration.
3136
/// </summary>
37+
[Key(3)]
3238
[JsonProperty("clientId")]
3339
public string ClientId { get; set; }
3440

3541
/// <summary>
3642
/// Device Metadata. It's a flexible key value pair. Usually used to tag devices.
3743
/// </summary>
44+
[Key(4)]
3845
[JsonProperty("metadata")]
3946
public JObject Metadata { get; set; }
4047

4148
/// <summary>
4249
/// Push registration data.
4350
/// </summary>
51+
[Key(5)]
4452
[JsonProperty("push")]
4553
public PushData Push { get; set; } = new PushData();
4654

4755
/// <summary>
4856
/// Random string which is automatically generated when a new LocalDevice is created and can be used to authenticate PushAdmin Rest requests.
4957
/// </summary>
58+
[Key(6)]
5059
[JsonProperty("deviceSecret")]
5160
public string DeviceSecret { get; set; }
5261

5362
/// <summary>
5463
/// Class describing Push data.
5564
/// </summary>
65+
[MessagePackObject]
5666
public class PushData
5767
{
5868
/// <summary>
5969
/// Push Recipient. Currently supporter recipients are Apple (apns), Google (fcm) and Browser (web).
6070
/// For more information - https://ably.com/docs/rest-api#post-device-registration.
6171
/// </summary>
72+
[Key(0)]
6273
[JsonProperty("recipient")]
6374
public JObject Recipient { get; set; }
6475

6576
/// <summary>
6677
/// State of the push integration.
6778
/// </summary>
79+
[Key(1)]
6880
[JsonProperty("state")]
6981
public string State { get; set; }
7082

7183
/// <summary>
7284
/// Error registering device as a PushTarget.
7385
/// </summary>
86+
[Key(2)]
7487
[JsonProperty("errorReason")]
7588
public ErrorInfo ErrorReason { get; set; }
7689
}

src/IO.Ably.Shared/Push/PushChannelSubscription.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
1-
using Newtonsoft.Json;
1+
using MsgPack.Serialization;
2+
using Newtonsoft.Json;
23

34
namespace IO.Ably.Push
45
{
56
/// <summary>
67
/// Represents a push channel subscription.
78
/// </summary>
9+
[MessagePackObject]
810
public class PushChannelSubscription
911
{
1012
/// <summary>
1113
/// Name of the channel.
1214
/// </summary>
15+
[Key(0)]
1316
[JsonProperty("channel")]
1417
public string Channel { get; set; }
1518

1619
/// <summary>
1720
/// Device id attached to the subscription.
1821
/// </summary>
22+
[Key(1)]
1923
[JsonProperty("deviceId")]
2024
public string DeviceId { get; set; }
2125

2226
/// <summary>
2327
/// Client id attached to the channel.
2428
/// </summary>
29+
[Key(2)]
2530
[JsonProperty("clientId")]
2631
public string ClientId { get; set; }
2732

src/IO.Ably.Shared/Rest/ChannelDetails.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,100 @@
1-
using Newtonsoft.Json;
1+
using MsgPack.Serialization;
2+
using Newtonsoft.Json;
23

34
namespace IO.Ably.Rest
45
{
56
#pragma warning disable SA1307
67
#pragma warning disable SA1600
78

9+
[MessagePackObject]
810
public class ChannelDetails
911
{
1012
/// <summary>
1113
/// The required name of the channel including any qualifier, if any.
1214
/// </summary>
15+
[Key(0)]
1316
[JsonProperty("channelId")]
1417
public string ChannelId { get; set; }
1518

1619
/// <summary>
1720
/// The status and occupancy stats for the channel.
1821
/// </summary>
22+
[Key(1)]
1923
[JsonProperty("status")]
2024
public ChannelStatus Status { get; set; }
2125
}
2226

27+
[MessagePackObject]
2328
public class ChannelStatus
2429
{
2530
/// <summary>
2631
/// Indicates whether the channel that is the subject of the event is active.
2732
/// </summary>
33+
[Key(0)]
2834
[JsonProperty("isActive")]
2935
public bool IsActive { get; set; }
3036

3137
/// <summary>
3238
/// Metadata relating to the occupants of the channel.
3339
/// </summary>
40+
[Key(1)]
3441
[JsonProperty("occupancy")]
3542
public ChannelOccupancy Occupancy { get; set; }
3643
}
3744

3845
/// <summary>
3946
/// Metadata relating to the occupants of the channel.
4047
/// </summary>
48+
[MessagePackObject]
4149
public class ChannelOccupancy
4250
{
51+
[Key(0)]
4352
[JsonProperty("metrics")]
4453
public ChannelMetrics Metrics { get; set; }
4554
}
4655

56+
[MessagePackObject]
4757
public class ChannelMetrics
4858
{
4959
/// <summary>
5060
/// The number of connections.
5161
/// </summary>
62+
[Key(0)]
5263
[JsonProperty("connections")]
5364
public int Connections { get; set; }
5465

5566
/// <summary>
5667
/// The number of connections attached to the channel that are authorised to publish.
5768
/// </summary>
69+
[Key(1)]
5870
[JsonProperty("publishers")]
5971
public int Publishers { get; set; }
6072

6173
/// <summary>
6274
/// The number of connections attached that are authorised to subscribe to messages.
6375
/// </summary>
76+
[Key(2)]
6477
[JsonProperty("subscribers")]
6578
public int Subscribers { get; set; }
6679

6780
/// <summary>
6881
/// The number of connections that are authorised to enter members into the presence channel.
6982
/// </summary>
83+
[Key(3)]
7084
[JsonProperty("presenceConnections")]
7185
public int PresenceConnections { get; set; }
7286

7387
/// <summary>
7488
/// The number of members currently entered into the presence channel.
7589
/// </summary>
90+
[Key(4)]
7691
[JsonProperty("presenceMembers")]
7792
public int PresenceMembers { get; set; }
7893

7994
/// <summary>
8095
/// The number of connections that are authorised to subscribe to presence messages.
8196
/// </summary>
97+
[Key(5)]
8298
[JsonProperty("presenceSubscribers")]
8399
public int PresenceSubscribers { get; set; }
84100
}

0 commit comments

Comments
 (0)