private bool LeaveGroupWithAckMessageEqual(LeaveGroupWithAckMessage x, LeaveGroupWithAckMessage y) { return(StringEqual(x.ConnectionId, y.ConnectionId) && StringEqual(x.GroupName, y.GroupName) && x.AckId == y.AckId && x.TracingId == y.TracingId); }
public static void StartToRemoveConnectionFromGroup(ILogger logger, LeaveGroupWithAckMessage message) { if (!Enabled()) { return; } _startToRemoveConnectionFromGroup(logger, message.TracingId, message.ConnectionId, message.GroupName, null); }
public override Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default) { if (IsInvalidArgument(connectionId)) { throw new ArgumentException(NullOrEmptyStringErrorMessage, nameof(connectionId)); } if (IsInvalidArgument(groupName)) { throw new ArgumentException(NullOrEmptyStringErrorMessage, nameof(groupName)); } var message = new LeaveGroupWithAckMessage(connectionId, groupName); return(ServiceConnectionContainer.WriteAckableMessageAsync(message, cancellationToken)); }
public override Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default) { if (IsInvalidArgument(connectionId)) { throw new ArgumentException(NullOrEmptyStringErrorMessage, nameof(connectionId)); } if (IsInvalidArgument(groupName)) { throw new ArgumentException(NullOrEmptyStringErrorMessage, nameof(groupName)); } var message = new LeaveGroupWithAckMessage(connectionId, groupName).WithTracingId(); Log.StartToRemoveConnectionFromGroup(Logger, message); return(WriteAckableMessageAsync(message)); }
public IEnumerable <AppMessage> GetMessages(Message message) { if (message.IsCommand) { var command = _serializer.Parse <Command>(message.Value, message.Encoding); switch (command.CommandType) { case CommandType.AddToGroup: { // name is hg-{HubName}.{GroupName}, consider the whole as the actual group name // this message always goes through the appName-connection var groupName = command.Value; var connectionId = GetName(message.Key, PrefixHelper.ConnectionIdPrefix); var joinGroupWithAckMessage = new JoinGroupWithAckMessage(connectionId, groupName).WithTracingId(); if (joinGroupWithAckMessage.TracingId != null) { MessageLog.StartToAddConnectionToGroup(_logger, joinGroupWithAckMessage); } // go through the app connection // use groupName as the partitionkey so that commands towards the same group always goes into the same service connection yield return(new AppMessage(joinGroupWithAckMessage, message)); yield break; } case CommandType.RemoveFromGroup: { // this message always goes through the appName-connection var groupName = command.Value; var connectionId = GetName(message.Key, PrefixHelper.ConnectionIdPrefix); var leaveGroupWithAckMessage = new LeaveGroupWithAckMessage(connectionId, groupName).WithTracingId(); if (leaveGroupWithAckMessage.TracingId != null) { MessageLog.StartToRemoveConnectionFromGroup(_logger, leaveGroupWithAckMessage); } // go through the app connection // use groupName as the partitionkey so that commands towards the same group always goes into the same service connection yield return(new AppMessage(leaveGroupWithAckMessage, message)); yield break; } case CommandType.Initializing: yield break; case CommandType.Abort: yield break; } } var segment = GetPayload(message); // broadcast case if (TryGetName(message.Key, PrefixHelper.HubPrefix, out var hubName)) { var broadcastDataMessage = new BroadcastDataMessage(excludedList: GetExcludedIds(message.Filter), payloads: GetPayloads(segment)).WithTracingId(); if (broadcastDataMessage.TracingId != null) { MessageLog.StartToBroadcastMessage(_logger, broadcastDataMessage); } yield return(new HubMessage(hubName, broadcastDataMessage, message)); } // echo case else if (TryGetName(message.Key, PrefixHelper.HubConnectionIdPrefix, out _)) { // naming: hc-{HubName}.{ConnectionId} // ConnectionId can NEVER contain . var index = message.Key.LastIndexOf('.'); if (index < 0 || index == message.Key.Length - 1) { throw new ArgumentException($"Key must contain '.' in between but it is not: {message.Key}"); } var connectionId = message.Key.Substring(index + 1); var connectionDataMessage = new ConnectionDataMessage(connectionId, segment).WithTracingId(); if (connectionDataMessage.TracingId != null) { MessageLog.StartToSendMessageToConnection(_logger, connectionDataMessage); } // Go through the app connection yield return(new AppMessage(connectionDataMessage, message)); } // group broadcast case else if (TryGetName(message.Key, PrefixHelper.HubGroupPrefix, out _)) { // naming: hg-{HubName}.{GroupName}, it as a whole is the group name per the JoinGroup implementation // go through the app connection // use groupName as the partitionkey so that commands towards the same group always goes into the same service connection var groupName = message.Key; var groupBroadcastDataMessage = new GroupBroadcastDataMessage(groupName, excludedList: GetExcludedIds(message.Filter), payloads: GetPayloads(segment)).WithTracingId(); if (groupBroadcastDataMessage.TracingId != null) { MessageLog.StartToBroadcastMessageToGroup(_logger, groupBroadcastDataMessage); } yield return(new AppMessage(groupBroadcastDataMessage, message)); } // user case else if (TryGetName(message.Key, PrefixHelper.HubUserPrefix, out var userWithHubPrefix)) { // naming: hu-{HubName}.{UserName}, HubName can contain '.' and UserName can contain '.' // Go through all the possibilities foreach (var(hub, user) in GetPossibleNames(userWithHubPrefix)) { var userDataMessage = new UserDataMessage(user, GetPayloads(segment)).WithTracingId(); if (userDataMessage.TracingId != null) { MessageLog.StartToSendMessageToUser(_logger, userDataMessage); } // For old protocol, it is always single user per message https://github.com/SignalR/SignalR/blob/dev/src/Microsoft.AspNet.SignalR.Core/Infrastructure/Connection.cs#L162 yield return(new HubMessage(hub, userDataMessage, message)); } } else { throw new NotSupportedException($"Message {message.Key} is not supported."); } }