/// <inheritdoc /> public override async Task OnDisconnectedAsync(Exception exception) { NetworkEntityGuid guid = new NetworkEntityGuidBuilder() .WithId(int.Parse(Context.UserIdentifier)) .WithType(EntityType.Player) .Build(); //Right now this doesn't depend on entity, so we just do it. if (ZoneLookupService.Contains(Context.ConnectionId)) { ZoneLookupService.Unregister(Context.ConnectionId); } if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation($"About to attempt final cleanup for Entity: {guid}"); } //If the entity is no longer contained we should clear up FinalEntityLockResult entityLockResult = await EntityLockService.TryAquireFinalEntityLockAsync(guid); if (entityLockResult.Result) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation($"Clearing Entity data for Entity: {guid}. Last connection related to the Entity."); } using (entityLockResult.LockObject) { foreach (var c in EntityRemovable) { c.RemoveEntityEntry(guid); } } } else { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation($"Entity: {guid} still has active connections/sessions claiming interest. Won't cleanup entity data."); } //We still need to release interest //so that the ref count goes down, otherwise it'll never be cleaned up. await this.EntityLockService.ReleaseEntityInterestAsync(guid) .ConfigureAwait(false); } await base.OnDisconnectedAsync(exception); }
/// <inheritdoc /> public override async Task OnConnectedAsync() { await base.OnConnectedAsync() .ConfigureAwait(false); if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation($"Account Connected: {ClaimsReader.GetUserName(Context.User)}:{ClaimsReader.GetUserId(Context.User)}"); } NetworkEntityGuid guid = new NetworkEntityGuidBuilder() .WithId(int.Parse(Context.UserIdentifier)) .WithType(EntityType.Player) .Build(); //Register interest and then lock //We need to lock on the entity so only 1 connection for the entity can go through this process at a time. await EntityLockService.RegisterEntityInterestAsync(guid) .ConfigureAwait(false); using (await EntityLockService.AquireEntityLockAsync(guid).ConfigureAwait(false)) { try { foreach (var listener in OnConnectionHubListeners) { HubOnConnectionState connectionState = await listener.OnConnected(this).ConfigureAwait(false); //if the listener indicated we need to abort for whatever reason we //should believe it and just abort. if (connectionState == HubOnConnectionState.Abort) { Context.Abort(); break; } } } catch (Exception e) { if (Logger.IsEnabled(LogLevel.Error)) { Logger.LogInformation($"Account: {ClaimsReader.GetUserName(Context.User)}:{ClaimsReader.GetUserId(Context.User)} failed to properly connect to hub. Error: {e.Message}\n\nStack: {e.StackTrace}"); } Context.Abort(); } } }