public override Task OnDisconnectedAsync(HubConnectionContext connection) { _connections.Remove(connection); var tasks = new List <Task>(); var feature = connection.Features.Get <IRedisFeature>(); var redisSubscriptions = feature.Subscriptions; if (redisSubscriptions != null) { foreach (var subscription in redisSubscriptions) { RedisLog.Unsubscribe(_logger, subscription); tasks.Add(_bus.UnsubscribeAsync(subscription)); } } var groupNames = feature.Groups; if (groupNames != null) { // Copy the groups to an array here because they get removed from this collection // in RemoveGroupAsync foreach (var group in groupNames.ToArray()) { // Use RemoveGroupAsyncCore because the connection is local and we don't want to // accidentally go to other servers with our remove request. tasks.Add(RemoveGroupAsyncCore(connection, group)); } } return(Task.WhenAll(tasks)); }
public override Task OnDisconnectedAsync(HubConnectionContext connection) { _connections.Remove(connection); var tasks = new List <Task>(); var connectionChannel = _channels.Connection(connection.ConnectionId); RedisLog.Unsubscribe(_logger, connectionChannel); tasks.Add(_bus.UnsubscribeAsync(connectionChannel)); var feature = connection.Features.Get <IRedisFeature>(); var groupNames = feature.Groups; if (groupNames != null) { // Copy the groups to an array here because they get removed from this collection // in RemoveFromGroupAsync foreach (var group in groupNames.ToArray()) { // Use RemoveGroupAsyncCore because the connection is local and we don't want to // accidentally go to other servers with our remove request. tasks.Add(RemoveGroupAsyncCore(connection, group)); } } if (!string.IsNullOrEmpty(connection.UserIdentifier)) { tasks.Add(RemoveUserAsync(connection)); } return(Task.WhenAll(tasks)); }
private Task RemoveUserAsync(HubConnectionContext connection) { var userChannel = _channels.User(connection.UserIdentifier); return(_users.RemoveSubscriptionAsync(userChannel, connection, async channelName => { RedisLog.Unsubscribe(_logger, channelName); await _bus.UnsubscribeAsync(channelName); })); }
/// <summary> /// This takes <see cref="HubConnectionContext"/> because we want to remove the connection from the /// _connections list in OnDisconnectedAsync and still be able to remove groups with this method. /// </summary> private async Task RemoveGroupAsyncCore(HubConnectionContext connection, string groupName) { var groupChannel = _channels.Group(groupName); await _groups.RemoveSubscriptionAsync(groupChannel, connection, async channelName => { RedisLog.Unsubscribe(_logger, channelName); await _bus.UnsubscribeAsync(channelName); }); var feature = connection.Features.Get <IRedisFeature>(); var groupNames = feature.Groups; if (groupNames != null) { lock (groupNames) { groupNames.Remove(groupName); } } }
/// <summary> /// This takes <see cref="HubConnectionContext"/> because we want to remove the connection from the /// _connections list in OnDisconnectedAsync and still be able to remove groups with this method. /// </summary> private async Task RemoveGroupAsyncCore(HubConnectionContext connection, string groupName) { var groupChannel = _channels.Group(groupName); if (!_groups.TryGetValue(groupChannel, out var group)) { return; } var feature = connection.Features.Get <IRedisFeature>(); var groupNames = feature.Groups; if (groupNames != null) { lock (groupNames) { groupNames.Remove(groupName); } } await group.Lock.WaitAsync(); try { if (group.Connections.Count > 0) { group.Connections.Remove(connection); if (group.Connections.Count == 0) { RedisLog.Unsubscribe(_logger, groupChannel); await _bus.UnsubscribeAsync(groupChannel); } } } finally { group.Lock.Release(); } }