From 4d1a1e530e00629a51f907a227c9c1186becd7b6 Mon Sep 17 00:00:00 2001 From: Julien Foret <30928890+julienforet@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:14:05 +0200 Subject: [PATCH 1/5] use named templating in log messages (#1797) * remove not named templating * fix: fix formatting issue in unit tests --- .../Logging/MessageLog.cs | 58 +++++++++-------- .../Logging/MessageLogTests.cs | 62 ++++++++++++++----- 2 files changed, 80 insertions(+), 40 deletions(-) diff --git a/src/Microsoft.Azure.SignalR.Common/Logging/MessageLog.cs b/src/Microsoft.Azure.SignalR.Common/Logging/MessageLog.cs index 8a2711590..ba2d2b815 100644 --- a/src/Microsoft.Azure.SignalR.Common/Logging/MessageLog.cs +++ b/src/Microsoft.Azure.SignalR.Common/Logging/MessageLog.cs @@ -9,26 +9,31 @@ namespace Microsoft.Azure.SignalR { internal static class MessageLog { - public const string StartToBroadcastMessageTemplate = "Start to broadcast message {0}."; - public const string StartToBroadcastMessageWithExcludedConnectionTemplate = "Start to broadcast message {0} except for {1} connections {2}."; - public const string StartToSendMessageToConnectionsTemplate = "Start to send message {0} to {1} connections {2}."; - public const string StartToSendMessageToConnectionTemplate = "Start to send message {0} to connection {1}."; - public const string StartToBroadcastMessageToGroupTemplate = "Start to broadcast message {0} to group {1}."; - public const string StartToBroadcastMessageToGroupWithExcludedConnectionsTemplate = "Start to broadcast message {0} to group {1} except for {2} connections {3}."; - public const string StartToBroadcastMessageToGroupsTemplate = "Start to broadcast message {0} to {1} groups {2}."; - public const string StartToSendMessageToUserTemplate = "Start to send message {0} to user {1}."; - public const string StartToSendMessageToUsersTemplate = "Start to send message {0} to {1} users {2}."; - public const string StartToAddConnectionToGroupTemplate = "Start to send message {0} to add connection {1} to group {2}."; - public const string StartToRemoveConnectionFromGroupTemplate = "Start to send message {0} to remove connection {1} from group {2}."; - public const string StartToAddUserToGroupTemplate = "Start to send message {0} to add user {1} to group {2}."; - public const string StartToAddUserToGroupWithTtlTemplate = "Start to send message {0} to add user {1} to group {2} with TTL {3} seconds."; - public const string StartToRemoveUserFromGroupTemplate = "Start to send message {0} to remove user {1} from group {2}."; - public const string StartToRemoveUserFromAllGroupsTemplate = "Start to send message {0} to remove user {1} from all groups."; - public const string StartToRemoveConnectionFromAllGroupsTemplate = "Start to send message {0} to remove connection {1} from all groups."; - public const string StartToCheckIfUserInGroupTemplate = "Start to send message {0} to check if user {1} in group {2}."; - public const string FailedToSendMessageTemplate = "Failed to send message {0}."; - public const string SucceededToSendMessageTemplate = "Succeeded to send message {0}."; - + public const string StartToBroadcastMessageTemplate = "Start to broadcast message {tracingId}."; + public const string StartToBroadcastMessageWithExcludedConnectionTemplate = "Start to broadcast message {tracingId} except for {excludedCount} connections {excludedList}."; + public const string StartToSendMessageToConnectionsTemplate = "Start to send message {tracingId} to {connectionsCount} connections {connectionsList}."; + public const string StartToSendMessageToConnectionTemplate = "Start to send message {tracingId} to connection {connectionId}."; + public const string StartToBroadcastMessageToGroupTemplate = "Start to broadcast message {tracingId} to group {group}."; + public const string StartToBroadcastMessageToGroupWithExcludedConnectionsTemplate = "Start to broadcast message {tracingId} to group {group} except for {excludedCount} connections {connectionsList}."; + public const string StartToBroadcastMessageToGroupsTemplate = "Start to broadcast message {tracingId} to {groupsCount} groups {groupsList}."; + public const string StartToSendMessageToUserTemplate = "Start to send message {tracingId} to user {userId}."; + public const string StartToSendMessageToUsersTemplate = "Start to send message {tracingId} to {usersCount} users {usersList}."; + public const string StartToAddConnectionToGroupTemplate = "Start to send message {tracingId} to add connection {connectionId} to group {group}."; + public const string StartToRemoveConnectionFromGroupTemplate = "Start to send message {tracingId} to remove connection {connectionId} from group {group}."; + public const string StartToAddUserToGroupTemplate = "Start to send message {tracingId} to add user {userId} to group {group}."; + public const string StartToAddUserToGroupWithTtlTemplate = "Start to send message {tracingId} to add user {userId} to group {group} with TTL {timeToLive} seconds."; + public const string StartToRemoveUserFromGroupTemplate = "Start to send message {tracingId} to remove user {userId} from group {group}."; + public const string StartToRemoveUserFromAllGroupsTemplate = "Start to send message {tracingId} to remove user {userId} from all groups."; + public const string StartToRemoveConnectionFromAllGroupsTemplate = "Start to send message {tracingId} to remove connection {connectionId} from all groups."; + public const string StartToCheckIfUserInGroupTemplate = "Start to send message {tracingId} to check if user {userId} in group {group}."; + public const string FailedToSendMessageTemplate = "Failed to send message {tracingId}."; + public const string SucceededToSendMessageTemplate = "Succeeded to send message {tracingId}."; + public const string ReceivedMessageFromClientConnectionTemplate = "Received message {tracingId} from client connection {connectionId}."; + public const string StartToSendMessageToCloseConnectionTemplate = "Start to send message {tracingId} to close connection {connectionId} for reason: '{reason}'."; + public const string StartToSendMessageToCheckConnectionTemplate = "Start to send message {tracingId} to check if connection {connectionId} exists."; + public const string StartToSendMessageToCheckIfUserExistsTemplate = "Start to send message {tracingId} to check if user {userId} exists."; + public const string StartToSendMessageToCheckIfGroupExistsTemplate = "Start to send message {tracingId} to check if group {group} exists."; + private static readonly Action _startToBroadcastMessage = LoggerMessage.Define( LogLevel.Information, @@ -141,7 +146,7 @@ internal static class MessageLog LoggerMessage.Define( LogLevel.Information, new EventId(120, "RecieveMessageFromService"), - "Received message {tracingId} from client connection {connectionId}."); + ReceivedMessageFromClientConnectionTemplate); private static readonly Action _startToCheckIfUserInGroup = LoggerMessage.Define( @@ -153,24 +158,25 @@ internal static class MessageLog LoggerMessage.Define( LogLevel.Information, new EventId(140, "StartToCloseConnection"), - "Start to send message {tracingId} to close connection {connectionId} for reason: '{reason}'."); + StartToSendMessageToCloseConnectionTemplate); - private static readonly Action _startToCheckIfConnectionExists = LoggerMessage.Define( + private static readonly Action _startToCheckIfConnectionExists = + LoggerMessage.Define( LogLevel.Information, new EventId(150, "StartToCheckIfConnectionExists"), - "Start to send message {tracingId} to check if connection {connectionId} exists."); + StartToSendMessageToCheckConnectionTemplate); private static readonly Action _startToCheckIfUserExists = LoggerMessage.Define( LogLevel.Information, new EventId(160, "StartToCheckIfUserExists"), - "Start to send message {tracingId} to check if user {userId} exists."); + StartToSendMessageToCheckIfUserExistsTemplate); private static readonly Action _startToCheckIfGroupExists = LoggerMessage.Define( LogLevel.Information, new EventId(170, "StartToCheckIfGroupExists"), - "Start to send message {tracingId} to check if group {group} exists."); + StartToSendMessageToCheckIfGroupExistsTemplate); public static void ReceiveMessageFromService(ILogger logger, ConnectionDataMessage message) { diff --git a/test/Microsoft.Azure.SignalR.Tests/Logging/MessageLogTests.cs b/test/Microsoft.Azure.SignalR.Tests/Logging/MessageLogTests.cs index e186452bc..4b4dfbcc8 100644 --- a/test/Microsoft.Azure.SignalR.Tests/Logging/MessageLogTests.cs +++ b/test/Microsoft.Azure.SignalR.Tests/Logging/MessageLogTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Text.RegularExpressions; using Microsoft.Azure.SignalR.Protocol; using Microsoft.Extensions.Logging; using Xunit; @@ -19,51 +20,84 @@ public void MessageLogTest() { // broadcast MessageLog.StartToBroadcastMessage(logger, new BroadcastDataMessage(null, 123UL)); - Assert.Equal(string.Format(MessageLog.StartToBroadcastMessageTemplate, 123UL), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToBroadcastMessageTemplate, 123UL), logger.LogStr); MessageLog.StartToBroadcastMessage(logger, new BroadcastDataMessage(new[] { "x", "y" }, new Dictionary>(), 123UL)); - Assert.Equal(string.Format(MessageLog.StartToBroadcastMessageWithExcludedConnectionTemplate, 123UL, 2, "x, y"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToBroadcastMessageWithExcludedConnectionTemplate, 123UL, 2, "x, y"), logger.LogStr); // send to connections + MessageLog.StartToSendMessageToConnection(logger, new ConnectionDataMessage("id1", null, tracingId: 123UL)); + Assert.Equal(Format(MessageLog.StartToSendMessageToConnectionTemplate, 123UL, "id1"), logger.LogStr); + MessageLog.StartToSendMessageToConnections(logger, new MultiConnectionDataMessage(new[] { "id1", "id2" }, null, tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToSendMessageToConnectionsTemplate, 123UL, 2, "id1, id2"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToSendMessageToConnectionsTemplate, 123UL, 2, "id1, id2"), logger.LogStr); // send to user/users MessageLog.StartToSendMessageToUser(logger, new UserDataMessage("user", null, tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToSendMessageToUserTemplate, 123UL, "user"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToSendMessageToUserTemplate, 123UL, "user"), logger.LogStr); + MessageLog.FailedToSendMessage(logger, new UserDataMessage("user", null, tracingId: 123UL), new Exception()); + Assert.Equal(Format(MessageLog.FailedToSendMessageTemplate, 123UL), logger.LogStr); + + MessageLog.SucceededToSendMessage(logger, new UserDataMessage("user", null, tracingId: 123UL)); + Assert.Equal(Format(MessageLog.SucceededToSendMessageTemplate, 123UL), logger.LogStr); + + MessageLog.ReceiveMessageFromService(logger, new ConnectionDataMessage("c", null, tracingId: 123UL)); + Assert.Equal(Format(MessageLog.ReceivedMessageFromClientConnectionTemplate, 123UL, "c"), logger.LogStr); + MessageLog.StartToSendMessageToUsers(logger, new MultiUserDataMessage(new[] { "u1", "u2" }, null, tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToSendMessageToUsersTemplate, 123UL, 2, "u1, u2"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToSendMessageToUsersTemplate, 123UL, 2, "u1, u2"), logger.LogStr); // send to group/groups MessageLog.StartToBroadcastMessageToGroup(logger, new GroupBroadcastDataMessage("g", null, tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToBroadcastMessageToGroupTemplate, 123UL, "g"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToBroadcastMessageToGroupTemplate, 123UL, "g"), logger.LogStr); MessageLog.StartToBroadcastMessageToGroup(logger, new GroupBroadcastDataMessage("g", new[] { "c1", "c2" }, null, tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToBroadcastMessageToGroupWithExcludedConnectionsTemplate, 123UL, "g", 2, "c1, c2"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToBroadcastMessageToGroupWithExcludedConnectionsTemplate, 123UL, "g", 2, "c1, c2"), logger.LogStr); MessageLog.StartToBroadcastMessageToGroups(logger, new MultiGroupBroadcastDataMessage(new[] { "g1", "g2" }, null, tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToBroadcastMessageToGroupsTemplate, 123UL, 2, "g1, g2"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToBroadcastMessageToGroupsTemplate, 123UL, 2, "g1, g2"), logger.LogStr); // connection join/leave group MessageLog.StartToAddConnectionToGroup(logger, new JoinGroupWithAckMessage("c", "g", tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToAddConnectionToGroupTemplate, 123UL, "c", "g"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToAddConnectionToGroupTemplate, 123UL, "c", "g"), logger.LogStr); MessageLog.StartToRemoveConnectionFromGroup(logger, new LeaveGroupWithAckMessage("c", "g", tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToRemoveConnectionFromGroupTemplate, 123UL, "c", "g"), logger.LogStr); - + Assert.Equal(Format(MessageLog.StartToRemoveConnectionFromGroupTemplate, 123UL, "c", "g"), logger.LogStr); + + MessageLog.StartToCloseConnection(logger, new CloseConnectionMessage("c", "e") { TracingId = 123UL}); + Assert.Equal(Format(MessageLog.StartToSendMessageToCloseConnectionTemplate, 123UL, "c", "e"), logger.LogStr); + + MessageLog.StartToCheckIfConnectionExists(logger, new CheckConnectionExistenceWithAckMessage("c", 12, 123UL)); + Assert.Equal(Format(MessageLog.StartToSendMessageToCheckConnectionTemplate, 123UL, "c"), logger.LogStr); + + MessageLog.StartToCheckIfUserExists(logger, new CheckUserExistenceWithAckMessage("c", 12, 123UL)); + Assert.Equal(Format(MessageLog.StartToSendMessageToCheckIfUserExistsTemplate, 123UL, "c"), logger.LogStr); + + MessageLog.StartToCheckIfGroupExists(logger, new CheckGroupExistenceWithAckMessage("c", 12, 123UL)); + Assert.Equal(Format(MessageLog.StartToSendMessageToCheckIfGroupExistsTemplate, 123UL, "c"), logger.LogStr); + // user join/leave group MessageLog.StartToAddUserToGroup(logger, new UserJoinGroupMessage("c", "g", tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToAddUserToGroupTemplate, 123UL, "c", "g"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToAddUserToGroupTemplate, 123UL, "c", "g"), logger.LogStr); + + MessageLog.StartToCheckIfUserInGroup(logger, new CheckUserInGroupWithAckMessage("c", "g", tracingId: 123UL)); + Assert.Equal(Format(MessageLog.StartToCheckIfUserInGroupTemplate, 123UL, "c", "g"), logger.LogStr); MessageLog.StartToRemoveUserFromGroup(logger, new UserLeaveGroupMessage("c", "g", tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToRemoveUserFromGroupTemplate, 123UL, "c", "g"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToRemoveUserFromGroupTemplate, 123UL, "c", "g"), logger.LogStr); MessageLog.StartToRemoveUserFromGroup(logger, new UserLeaveGroupMessage("c", null, tracingId: 123UL)); - Assert.Equal(string.Format(MessageLog.StartToRemoveUserFromAllGroupsTemplate, 123UL, "c"), logger.LogStr); + Assert.Equal(Format(MessageLog.StartToRemoveUserFromAllGroupsTemplate, 123UL, "c"), logger.LogStr); } } + private string Format(string logTemplate, params object[] values) + { + var index = 0; + return Regex.Replace(logTemplate, "{[^}]*}", _ => values[index++].ToString()); + } + private class TestLogger : ILogger { public string LogStr { get; private set; } From a797495fc6c7069dc9c1c9fad6f5e294fbd1a0db Mon Sep 17 00:00:00 2001 From: ranjithsnair Date: Thu, 10 Aug 2023 14:42:10 +0800 Subject: [PATCH 2/5] Timeout has been increased to 100 seconds (#1812) Current timeout of 10 seconds is insufficient for generating a token and calling the AccessKey endpoint with ServerEndpoint proxy. Running it through Visual Studio, a task cancellation error occurs consistently. To resolve this issue, the timeout has been increased to 100 seconds, which is the default HTTP timeout. --- src/Microsoft.Azure.SignalR.Common/Endpoints/AadAccessKey.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Azure.SignalR.Common/Endpoints/AadAccessKey.cs b/src/Microsoft.Azure.SignalR.Common/Endpoints/AadAccessKey.cs index 76b982875..874961eed 100644 --- a/src/Microsoft.Azure.SignalR.Common/Endpoints/AadAccessKey.cs +++ b/src/Microsoft.Azure.SignalR.Common/Endpoints/AadAccessKey.cs @@ -24,7 +24,7 @@ internal class AadAccessKey : AccessKey internal const int GetTokenMaxRetryTimes = 3; - internal static readonly TimeSpan AuthorizeTimeout = TimeSpan.FromSeconds(10); + internal static readonly TimeSpan AuthorizeTimeout = TimeSpan.FromSeconds(100); private const string DefaultScope = "https://signalr.azure.com/.default"; From 189ac7be28f0939d635adac1b684518c022a9f26 Mon Sep 17 00:00:00 2001 From: Terence Fan Date: Thu, 10 Aug 2023 16:11:59 +0800 Subject: [PATCH 3/5] update SDK version (#1817) --- version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.props b/version.props index 52bd7c68d..db086f9d5 100644 --- a/version.props +++ b/version.props @@ -1,7 +1,7 @@ - 1.21.5 + 1.21.6 1.1.0 1.9.0 From 06c5071f1f31ee100aab1d762788d1f3c7f08a40 Mon Sep 17 00:00:00 2001 From: JialinXin Date: Tue, 22 Aug 2023 16:08:09 +0800 Subject: [PATCH 4/5] update doc about client invocation limits. (#1820) --- specs/ClientInvocation.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/ClientInvocation.md b/specs/ClientInvocation.md index 3352808a7..06be5b9d5 100644 --- a/specs/ClientInvocation.md +++ b/specs/ClientInvocation.md @@ -66,4 +66,5 @@ Basically the process is similar and the major different is that service underst > > * Service cached pending invocations for at most __10 minutes__ for memory concerns and will notify server when timeout. > * Serverless is __NOT__ supporeted in the first stage. -> * ASPNET SignalR is __NOT__ supported. \ No newline at end of file +> * ASPNET SignalR is __NOT__ supported. +> * Sharding is __NOT__ supported. Please use [Geo-Replication](https://learn.microsoft.com/azure/azure-signalr/howto-enable-geo-replication) for combined client invocation and large scale scenarios. \ No newline at end of file From d050dd2969f31bf74ced42f2943d41ca0fe3dbce Mon Sep 17 00:00:00 2001 From: Zhenghui Yan Date: Thu, 24 Aug 2023 11:08:26 +0800 Subject: [PATCH 5/5] add connection id in handshake response and add echo in ping. (#1821) --- .../ServiceConnections/ServiceConnectionBase.cs | 4 ++++ .../RuntimeServicePingMessages.cs | 6 ++++++ .../ServiceMessage.cs | 5 +++++ .../ServiceProtocol.cs | 7 ++++++- .../ServiceMessageEqualityComparer.cs | 3 ++- .../ServiceProtocolFacts.cs | 16 ++++++++++++++-- 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Azure.SignalR.Common/ServiceConnections/ServiceConnectionBase.cs b/src/Microsoft.Azure.SignalR.Common/ServiceConnections/ServiceConnectionBase.cs index 1ee45aa72..476f22025 100644 --- a/src/Microsoft.Azure.SignalR.Common/ServiceConnections/ServiceConnectionBase.cs +++ b/src/Microsoft.Azure.SignalR.Common/ServiceConnections/ServiceConnectionBase.cs @@ -299,6 +299,10 @@ protected Task OnServiceErrorAsync(ServiceErrorMessage serviceErrorMessage) protected virtual Task OnPingMessageAsync(PingMessage pingMessage) { + if (RuntimeServicePingMessage.IsEchoMessage(pingMessage)) + { + return WriteAsync(pingMessage); + } if (RuntimeServicePingMessage.TryGetOffline(pingMessage, out var instanceId)) { Log.ReceivedInstanceOfflinePing(Logger, instanceId); diff --git a/src/Microsoft.Azure.SignalR.Common/ServiceMessages/RuntimeServicePingMessages.cs b/src/Microsoft.Azure.SignalR.Common/ServiceMessages/RuntimeServicePingMessages.cs index ba0e4a575..341c64386 100644 --- a/src/Microsoft.Azure.SignalR.Common/ServiceMessages/RuntimeServicePingMessages.cs +++ b/src/Microsoft.Azure.SignalR.Common/ServiceMessages/RuntimeServicePingMessages.cs @@ -9,6 +9,7 @@ namespace Microsoft.Azure.SignalR { internal static class RuntimeServicePingMessage { + private const string EchoKey = "echo"; private const string OfflineKey = "offline"; private const string TargetKey = "target"; private const string StatusKey = "status"; @@ -52,6 +53,11 @@ internal static class RuntimeServicePingMessage private static readonly ServicePingMessage ServersTag = new ServicePingMessage { Messages = new[] { ServersKey, string.Empty } }; + public static bool IsEchoMessage(this ServicePingMessage ping) + { + return TryGetValue(ping, EchoKey, out _); + } + public static bool TryGetMessageLogEnableFlag(this ServicePingMessage ping, out bool enableMessageLog) { if (TryGetValue(ping, DiagnosticLogsMessagingTypeKey, out var value)) diff --git a/src/Microsoft.Azure.SignalR.Protocols/ServiceMessage.cs b/src/Microsoft.Azure.SignalR.Protocols/ServiceMessage.cs index 6944c526e..84cdbd30f 100644 --- a/src/Microsoft.Azure.SignalR.Protocols/ServiceMessage.cs +++ b/src/Microsoft.Azure.SignalR.Protocols/ServiceMessage.cs @@ -285,6 +285,11 @@ public class HandshakeResponseMessage : ExtensibleServiceMessage /// public string ErrorMessage { get; set; } + /// + /// Gets or sets the id of this connection. + /// + public string ConnectionId { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/src/Microsoft.Azure.SignalR.Protocols/ServiceProtocol.cs b/src/Microsoft.Azure.SignalR.Protocols/ServiceProtocol.cs index 3a218ec76..43727ffc8 100644 --- a/src/Microsoft.Azure.SignalR.Protocols/ServiceProtocol.cs +++ b/src/Microsoft.Azure.SignalR.Protocols/ServiceProtocol.cs @@ -319,10 +319,11 @@ private static void WriteHandshakeRequestMessage(ref MessagePackWriter writer, H private static void WriteHandshakeResponseMessage(ref MessagePackWriter writer, HandshakeResponseMessage message) { - writer.WriteArrayHeader(3); + writer.WriteArrayHeader(4); writer.Write(ServiceProtocolConstants.HandshakeResponseType); writer.Write(message.ErrorMessage); message.WriteExtensionMembers(ref writer); + writer.Write(message.ConnectionId); } private static void WriteAccessKeyRequestMessage(ref MessagePackWriter writer, AccessKeyRequestMessage message) @@ -800,6 +801,10 @@ private static HandshakeResponseMessage CreateHandshakeResponseMessage(ref Messa { result.ReadExtensionMembers(ref reader); } + if (arrayLength >= 4) + { + result.ConnectionId = ReadString(ref reader, "connectionId"); + } return result; } diff --git a/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceMessageEqualityComparer.cs b/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceMessageEqualityComparer.cs index fb6f83083..acfc302ed 100644 --- a/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceMessageEqualityComparer.cs +++ b/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceMessageEqualityComparer.cs @@ -118,7 +118,8 @@ private bool HandshakeRequestMessagesEqual(HandshakeRequestMessage x, HandshakeR private bool HandshakeResponseMessagesEqual(HandshakeResponseMessage x, HandshakeResponseMessage y) { - return StringEqual(x.ErrorMessage, y.ErrorMessage); + return StringEqual(x.ErrorMessage, y.ErrorMessage) && + StringEqual(x.ConnectionId, y.ConnectionId); } private bool AccessKeyRequestMessageEqual(AccessKeyRequestMessage x, AccessKeyRequestMessage y) diff --git a/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceProtocolFacts.cs b/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceProtocolFacts.cs index c270a6fa9..b0dd8aea3 100644 --- a/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceProtocolFacts.cs +++ b/test/Microsoft.Azure.SignalR.Protocols.Tests/ServiceProtocolFacts.cs @@ -90,10 +90,18 @@ public static IEnumerable TestParseOldData name: "HandshakeResponse_NoOptionalField", message: new HandshakeResponseMessage(), binary: "kgKg"), + new ProtocolTestData( + name: "HandshakeResponse_NoConnectionId", + message: new HandshakeResponseMessage(), + binary: "kwKggA=="), new ProtocolTestData( name: "HandshakeResponseWithError_NoOptionalField", message: new HandshakeResponseMessage("Version mismatch."), binary: "kgKxVmVyc2lvbiBtaXNtYXRjaC4="), + new ProtocolTestData( + name: "HandshakeResponseWithError_NoConnectionId", + message: new HandshakeResponseMessage("Version mismatch."), + binary: "kwKxVmVyc2lvbiBtaXNtYXRjaC6A"), new ProtocolTestData( name: "OpenConnection_NoOptionalField", message: new OpenConnectionMessage("conn1", null), @@ -280,11 +288,15 @@ public static IEnumerable TestParseOldData new ProtocolTestData( name: "HandshakeResponse", message: new HandshakeResponseMessage(), - binary: "kwKggA=="), + binary: "lAKggMA="), new ProtocolTestData( name: "HandshakeResponseWithError", message: new HandshakeResponseMessage("Version mismatch."), - binary: "kwKxVmVyc2lvbiBtaXNtYXRjaC6A"), + binary: "lAKxVmVyc2lvbiBtaXNtYXRjaC6AwA=="), + new ProtocolTestData( + name: "HandshakeResponseWithConnectionId", + message: new HandshakeResponseMessage() { ConnectionId = "abc" }, + binary: "lAKggKNhYmM="), new ProtocolTestData( name: "AccessKeyRequestMessage", message: new AccessKeyRequestMessage("token"),