Skip to content

Commit

Permalink
Merge pull request #1199 from ably/feature/integration-2.0
Browse files Browse the repository at this point in the history
[SDK-3703] Feature/integration 2.0
  • Loading branch information
sacOO7 authored Sep 25, 2023
2 parents b359101 + 5507611 commit 954ed28
Show file tree
Hide file tree
Showing 46 changed files with 1,283 additions and 1,121 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ jobs:
with:
dotnet-version: |
3.1.x
6.0.x
7.0.x
6.0.403
7.0.100
- name: Download fake-cli
run: dotnet tool restore
- name: Package
Expand All @@ -45,8 +45,8 @@ jobs:
with:
dotnet-version: |
3.1.x
6.0.x
7.0.x
6.0.403
7.0.100
- name: Download fake-cli
run: dotnet tool install fake-cli --version 5.20.4 --tool-path .
- name: Restore packages
Expand All @@ -73,7 +73,7 @@ jobs:
with:
dotnet-version: |
2.x.x
6.x.x
6.0.403
# Checkout unity packager
- name: Checkout unity-packager repo
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/run-tests-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
7.0.x
6.0.403
7.0.100
- name: Download dotnet build-script tools
run: dotnet tool restore
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/run-tests-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
7.0.x
6.0.403
7.0.100
- name: Download dotnet build-script tools
run: dotnet tool restore
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/run-tests-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
7.0.x
6.0.403
7.0.100
- name: Download dotnet build-script tools
run: dotnet tool restore
Expand Down
2 changes: 1 addition & 1 deletion src/IO.Ably.Shared/AblyRealtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal AblyRealtime(ClientOptions options, Func<ClientOptions, IMobileDevice,
RestClient = createRestFunc != null ? createRestFunc.Invoke(options, mobileDevice) : new AblyRest(options, mobileDevice);
Push = new PushRealtime(RestClient, Logger);

Connection = new Connection(this, options.NowFunc, options.Logger);
Connection = new Connection(this, options.NowFunc, Logger);
Connection.Initialise();

if (options.AutomaticNetworkStateMonitoring)
Expand Down
4 changes: 2 additions & 2 deletions src/IO.Ably.Shared/ClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ internal string GetClientId()
/// <summary>
/// A connection recovery string, specified by a client when initializing the library
/// with the intention of inheriting the state of an earlier connection. See the Ably
/// Realtime API documentation for further information on connection state recovery.
/// Realtime API documentation for further information on connection state recovery. (RTN16i)
/// Default: null.
/// </summary>
public string Recover { get; set; }
Expand Down Expand Up @@ -358,7 +358,7 @@ public bool UseBinaryProtocol
/// Default before 1.2: false.
/// Default from 1.2: true.
/// </summary>
public bool IdempotentRestPublishing { get; set; } = Defaults.ProtocolVersionNumber >= 1.2;
public bool IdempotentRestPublishing { get; set; } = true;

/// <summary>
/// Additional parameters to be sent in the querystring when initiating a realtime connection.
Expand Down
6 changes: 2 additions & 4 deletions src/IO.Ably.Shared/Defaults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

namespace IO.Ably
{
internal static class Defaults
internal class Defaults
{
internal static readonly float ProtocolVersionNumber = 1.2F;

internal static readonly string LibraryVersion = GetVersion();

internal static string GetVersion()
Expand All @@ -18,7 +16,7 @@ internal static string GetVersion()
return version.Split('.').Take(3).JoinStrings(".");
}

public static string ProtocolVersion { get; } = ProtocolVersionNumber.ToString(CultureInfo.InvariantCulture);
public const string ProtocolVersion = "2"; // CSV2

public const int QueryLimit = 100;

Expand Down
3 changes: 3 additions & 0 deletions src/IO.Ably.Shared/Extensions/PresenceExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ public static bool IsSynthesized(this PresenceMessage msg)
return msg.Id == null || !msg.Id.StartsWith(msg.ConnectionId);
}

// RTP2b, RTP2c
public static bool IsNewerThan(this PresenceMessage thisMessage, PresenceMessage thatMessage)
{
// RTP2b1
if (thisMessage.IsSynthesized() || thatMessage.IsSynthesized())
{
return thisMessage.Timestamp > thatMessage.Timestamp;
}

// RTP2b2
var thisValues = thisMessage.Id.Split(':');
var thatValues = thatMessage.Id.Split(':');

Expand Down
2 changes: 1 addition & 1 deletion src/IO.Ably.Shared/Http/AblyHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ internal void SetPreferredHost(string currentHost)
internal void CreateInternalHttpClient(TimeSpan timeout, HttpMessageHandler messageHandler)
{
Client = messageHandler != null ? new HttpClient(messageHandler) : new HttpClient();
Client.DefaultRequestHeaders.Add("X-Ably-Version", Defaults.ProtocolVersion);
Client.DefaultRequestHeaders.Add("X-Ably-Version", Defaults.ProtocolVersion); // RSC7a
Client.DefaultRequestHeaders.Add(Agent.AblyAgentHeader, Agent.AblyAgentIdentifier(Options.Agents)); // RSC7d
Client.Timeout = timeout;
}
Expand Down
1 change: 1 addition & 0 deletions src/IO.Ably.Shared/IO.Ably.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Realtime\Presence.GetParams.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Realtime\Presence.QueuedPresenceMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Realtime\PresenceMap.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Realtime\RecoveryKeyContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Realtime\Workflows\ChannelCommands.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Realtime\Workflows\IQueueCommand.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Realtime\Workflows\PingRequest.cs" />
Expand Down
38 changes: 25 additions & 13 deletions src/IO.Ably.Shared/Realtime/ChannelMessageProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,24 @@ public Task<bool> MessageReceived(ProtocolMessage protocolMessage, RealtimeState
return Task.FromResult(false);
}

// RTL15b
if (protocolMessage.ChannelSerial.IsNotEmpty() &&
(protocolMessage.Action == ProtocolMessage.MessageAction.Message ||
protocolMessage.Action == ProtocolMessage.MessageAction.Presence ||
protocolMessage.Action == ProtocolMessage.MessageAction.Attached))
{
Logger.Debug($"Setting channel serial for channelName - {channel.Name}," +
$"previous - {channel.Properties.ChannelSerial}, current - {protocolMessage.ChannelSerial}");
channel.Properties.ChannelSerial = protocolMessage.ChannelSerial;
}

switch (protocolMessage.Action)
{
case ProtocolMessage.MessageAction.Error:
channel.SetChannelState(ChannelState.Failed, protocolMessage);
break;
case ProtocolMessage.MessageAction.Attached:
channel.Properties.AttachSerial = protocolMessage.ChannelSerial;
channel.Properties.AttachSerial = protocolMessage.ChannelSerial; // RTL15a

if (protocolMessage.Flags.HasValue)
{
Expand All @@ -58,17 +69,15 @@ public Task<bool> MessageReceived(ProtocolMessage protocolMessage, RealtimeState
channel.Params = new ReadOnlyChannelParams(protocolMessage.Params);
}

if (channel.State == ChannelState.Attached)
// RTL12
if (channel.State == ChannelState.Attached && !protocolMessage.HasFlag(ProtocolMessage.Flag.Resumed))
{
// RTL12
if (!protocolMessage.HasFlag(ProtocolMessage.Flag.Resumed))
{
channel.Presence.ChannelAttached(protocolMessage);
channel.EmitUpdate(protocolMessage.Error, false, protocolMessage);
}
channel.Presence.ChannelAttached(protocolMessage, false);
channel.EmitErrorUpdate(protocolMessage.Error, false, protocolMessage);
}
else
{
channel.Presence.ChannelAttached(protocolMessage);
channel.SetChannelState(ChannelState.Attached, protocolMessage);
}

Expand Down Expand Up @@ -139,11 +148,14 @@ public Task<bool> MessageReceived(ProtocolMessage protocolMessage, RealtimeState
channel.OnError(presenceDecodeResult.Error);
}

string syncSerial = protocolMessage.Action == ProtocolMessage.MessageAction.Sync
? protocolMessage.ChannelSerial
: null;

channel.Presence.OnPresence(protocolMessage.Presence, syncSerial);
if (protocolMessage.Action == ProtocolMessage.MessageAction.Sync)
{
channel.Presence.OnSyncMessage(protocolMessage);
}
else
{
channel.Presence.OnPresence(protocolMessage.Presence);
}

break;
}
Expand Down
7 changes: 6 additions & 1 deletion src/IO.Ably.Shared/Realtime/ChannelProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
public class ChannelProperties
{
/// <summary>
/// contains the last channelSerial received in an ATTACHED ProtocolMessage for the channel, see RTL15a.
/// contains the channelSerial from latest ATTACHED ProtocolMessage received on the channel, see CP2a, RTL15a.
/// </summary>
public string AttachSerial { get; internal set; }

/// <summary>
/// contains the channelSerial from latest ProtocolMessage of action type Message/PresenceMessage received on the channel, see CP2b, RTL15b.
/// </summary>
public string ChannelSerial { get; internal set; }
}
}
38 changes: 25 additions & 13 deletions src/IO.Ably.Shared/Realtime/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using IO.Ably.Realtime.Workflow;
using IO.Ably.Shared.Realtime;
using IO.Ably.Transport;
using IO.Ably.Transport.States.Connection;

Expand Down Expand Up @@ -156,12 +157,6 @@ private void HandleNetworkStateChange(NetworkState state)
/// </summary>
public string Id => InnerState.Id;

/// <summary>
/// The serial number of the last message received on this connection.
/// The serial number may be used when recovering connection state.
/// </summary>
public long? Serial => InnerState.Serial;

internal long MessageSerial => InnerState.MessageSerial;

/// <summary>
Expand All @@ -172,18 +167,35 @@ private void HandleNetworkStateChange(NetworkState state)
/// <summary>
/// Indicates whether the current connection can be resumed.
/// </summary>
public bool ConnectionResumable => Key.IsNotEmpty() && Serial.HasValue;
public bool ConnectionResumable => Key.IsNotEmpty();

/// <summary>
/// Connection#recoveryKey is an attribute composed of the connectionKey, channelSerials, and the current msgSerial (RTN16m).
/// </summary>
[Obsolete("This property is deprecated, use CreateRecoveryKey method instead")]
public string RecoveryKey => CreateRecoveryKey();

/// <summary>
/// - (RTN16b) Connection#recoveryKey is an attribute composed of the connectionKey, and the latest connectionSerial received on the connection, and the current msgSerial.
/// Connection#CreateRecoveryKey is an attribute composed of the connectionKey, messageSerial and channelSerials (RTN16g, RTN16g1, RTN16h).
/// </summary>
public string RecoveryKey
/// <returns>recoveryKey.</returns>
public string CreateRecoveryKey()
{
get
if (Key.IsEmpty() || InnerState.State == Realtime.ConnectionState.Closing
|| InnerState.State == Realtime.ConnectionState.Closed
|| InnerState.State == Realtime.ConnectionState.Failed
|| InnerState.State == Realtime.ConnectionState.Suspended)
{
Debug.Assert(Serial.HasValue, "Expected a Value, found none");
return ConnectionResumable ? $"{Key}:{Serial.Value}:{MessageSerial}" : string.Empty;
return string.Empty;
}

var recoveryContext = new RecoveryKeyContext()
{
MsgSerial = MessageSerial,
ConnectionKey = Key,
ChannelSerials = RealtimeClient.Channels.GetChannelSerials(),
};
return recoveryContext.Encode();
}

/// <summary>
Expand All @@ -197,7 +209,7 @@ public string RecoveryKey
/// message and, in the failed state in particular, provides diagnostic
/// error information.
/// </summary>
public ErrorInfo ErrorReason => InnerState.ErrorReason;
public ErrorInfo ErrorReason => InnerState.ErrorReason; // RTN15c7

/// <summary>
/// Gets the currently used Host.
Expand Down
Loading

0 comments on commit 954ed28

Please sign in to comment.