public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList <string> excludedIds, CancellationToken cancellationToken = default)
        {
            if (IsInvalidArgument(methodName))
            {
                throw new ArgumentException(NullOrEmptyStringErrorMessage, nameof(methodName));
            }

            var message = new BroadcastDataMessage(excludedIds, SerializeAllProtocols(methodName, args)).WithTracingId();

            if (message.TracingId != null)
            {
                MessageLog.StartToBroadcastMessage(Logger, message);
            }
            return(WriteAsync(message));
        }
Exemplo n.º 2
0
 private static HubMessage ParseBroadcastDataMessageJson(BroadcastDataMessage bdm, IInvocationBinder binder)
 {
     foreach (var payload in bdm.Payloads)
     {
         if (payload.Key == "json")
         {
             var sequence = new ReadOnlySequence <byte>(payload.Value);
             if (_signalRPro.TryParseMessage(ref sequence, binder, out var signalRRRmessage))
             {
                 return(signalRRRmessage);
             }
         }
     }
     return(null);
 }
Exemplo n.º 3
0
            public static void StartToBroadcastMessage(ILogger logger, BroadcastDataMessage message)
            {
                if (!Enabled())
                {
                    return;
                }

                if (message.ExcludedList == null || message.ExcludedList.Count == 0)
                {
                    _startToBroadcastMessage(logger, message.TracingId, null);
                }
                else
                {
                    // todo: ? should we hide some by "..." if the excluded list is too long (max count: 20) - e.g. "excecpt for <list count> connections: connId1, connId2, ..."
                    var excludedConnections = string.Join(", ", message.ExcludedList);
                    _startToBroadcastMessageWithExcludedConnection(logger, message.TracingId, message.ExcludedList.Count, excludedConnections, null);
                }
            }
Exemplo n.º 4
0
 private static HubMessage ParseBroadcastDataMessageJson(BroadcastDataMessage bdm, IInvocationBinder binder)
 {
     foreach (var payload in bdm.Payloads)
     {
         if (payload.Key == "json")
         {
             var sequence = new ReadOnlySequence <byte>(payload.Value);
             if (_signalRPro.TryParseMessage(ref sequence, binder, out var signalRRRmessage))
             {
                 if (signalRRRmessage is InvocationMessage inv)
                 {
                     Console.WriteLine($" -- {bdm}: callback#  {inv.Target} {inv.Arguments[0]}");
                 }
                 else
                 {
                     Console.WriteLine($"oh something else {signalRRRmessage}");
                 }
                 return(signalRRRmessage);
             }
             else
             {
                 Console.WriteLine("failed..");
             }
         }
 private bool BroadcastDataMessagesEqual(BroadcastDataMessage x, BroadcastDataMessage y)
 {
     return(SequenceEqual(x.ExcludedList, y.ExcludedList) &&
            PayloadsEqual(x.Payloads, y.Payloads));
 }
Exemplo n.º 6
0
        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.");
            }
        }