public override Task SendGroupAsync(string groupName, string methodName, object[] args)
        {
            if (groupName == null)
            {
                throw new ArgumentNullException(nameof(groupName));
            }

            var group = _groups[groupName];

            if (group != null)
            {
                // Can't optimize for sending to a single connection in a group because
                // group might be modified inbetween checking and sending
                List <Task>          tasks   = null;
                SerializedHubMessage message = null;
                SendToGroupConnections(methodName, args, group, null, ref tasks, ref message);

                if (tasks != null)
                {
                    return(Task.WhenAll(tasks));
                }
            }

            return(Task.CompletedTask);
        }
        public override Task SendGroupsAsync(IReadOnlyList <string> groupNames, string methodName, object[] args)
        {
            // Each task represents the list of tasks for each of the writes within a group
            List <Task>          tasks   = null;
            SerializedHubMessage message = null;

            foreach (var groupName in groupNames)
            {
                if (string.IsNullOrEmpty(groupName))
                {
                    throw new InvalidOperationException("Cannot send to an empty group name.");
                }

                var group = _groups[groupName];
                if (group != null)
                {
                    SendToGroupConnections(methodName, args, group, null, ref tasks, ref message);
                }
            }

            if (tasks != null)
            {
                return(Task.WhenAll(tasks));
            }

            return(Task.CompletedTask);
        }
Beispiel #3
0
        // Tasks and message are passed by ref so they can be lazily created inside the method post-filtering,
        // while still being re-usable when sending to multiple groups
        private void SendToGroupConnections(string methodName, object[] args, ConcurrentDictionary <string, HubConnectionContext> connections, Func <HubConnectionContext, bool> include,
                                            ref List <Task> tasks, ref SerializedHubMessage message, CancellationToken cancellationToken)
        {
            // foreach over ConcurrentDictionary avoids allocating an enumerator
            foreach (var connection in connections)
            {
                if (include != null && !include(connection.Value))
                {
                    continue;
                }

                if (message == null)
                {
                    message = CreateSerializedInvocationMessage(methodName, args);
                }

                var task = connection.Value.WriteAsync(message, cancellationToken);

                if (!task.IsCompletedSuccessfully)
                {
                    if (tasks == null)
                    {
                        tasks = new List <Task>();
                    }

                    tasks.Add(task.AsTask());
                }
            }
        }
        private Task SendToAllConnections(string methodName, object[] args, Func <HubConnectionContext, bool> include)
        {
            List <Task>          tasks   = null;
            SerializedHubMessage message = null;

            // foreach over HubConnectionStore avoids allocating an enumerator
            foreach (var connection in _connections)
            {
                if (include != null && !include(connection))
                {
                    continue;
                }

                if (message == null)
                {
                    message = CreateSerializedInvocationMessage(methodName, args);
                }

                var task = connection.WriteAsync(message);

                if (!task.IsCompletedSuccessfully)
                {
                    if (tasks == null)
                    {
                        tasks = new List <Task>();
                    }

                    tasks.Add(task.AsTask());
                }
            }

            if (tasks == null)
            {
                return(Task.CompletedTask);
            }

            // Some connections are slow
            return(Task.WhenAll(tasks));
        }
        public override Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList <string> excludedIds)
        {
            if (groupName == null)
            {
                throw new ArgumentNullException(nameof(groupName));
            }

            var group = _groups[groupName];

            if (group != null)
            {
                List <Task>          tasks   = null;
                SerializedHubMessage message = null;

                SendToGroupConnections(methodName, args, group, connection => !excludedIds.Contains(connection.ConnectionId), ref tasks, ref message);

                if (tasks != null)
                {
                    return(Task.WhenAll(tasks));
                }
            }

            return(Task.CompletedTask);
        }