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)); }
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); }
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); } }
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)); }
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."); } }