using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Sockets; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using SocketsSample.EndPoints.Hubs; using SocketsSample.Hubs; namespace SocketsSample { public class HubEndPoint : RpcEndpoint, IHubConnectionContext where THub : Hub { private readonly AllClientProxy _all; private readonly HubLifetimeManager _lifetimeManager; public HubEndPoint(HubLifetimeManager lifetimeManager, InvocationAdapterRegistry registry, ILoggerFactory loggerFactory, IServiceScopeFactory serviceScopeFactory) : base(registry, loggerFactory, serviceScopeFactory) { _lifetimeManager = lifetimeManager; _all = new AllClientProxy(_lifetimeManager); } public virtual IClientProxy All => _all; public virtual IClientProxy Client(string connectionId) { return new SingleClientProxy(_lifetimeManager, connectionId); } public virtual IClientProxy Group(string groupName) { return new GroupProxy(_lifetimeManager, groupName); } public virtual IClientProxy User(string userId) { return new UserProxy(_lifetimeManager, userId); } public override async Task OnConnected(Connection connection) { try { await _lifetimeManager.OnConnectedAsync(connection); using (var scope = _serviceScopeFactory.CreateScope()) { var hub = scope.ServiceProvider.GetService() ?? Activator.CreateInstance(); Initialize(connection, hub); await hub.OnConnectedAsync(); } await base.OnConnected(connection); } finally { using (var scope = _serviceScopeFactory.CreateScope()) { var hub = scope.ServiceProvider.GetService() ?? Activator.CreateInstance(); Initialize(connection, hub); await hub.OnDisconnectedAsync(); } await _lifetimeManager.OnDisconnectedAsync(connection); } } protected override void BeforeInvoke(Connection connection, THub hub) { Initialize(connection, hub); } private void Initialize(Connection connection, THub hub) { hub.Clients = this; hub.Context = new HubCallerContext(connection); hub.Groups = new GroupManager(connection, _lifetimeManager); } protected override void AfterInvoke(Connection connection, THub endpoint) { // Poison the hub make sure it can't be used after invocation } } }