.NET Core SignalR Redis底板详解(一)

其实微软在.NET Framework时代就有Redis和Signalr的解决方案了。只不过我没有花心思去找源码。.NET Core版本的源码倒是很全。我们在用signalR的时候。是会先创建一个ChatHub继承Hub

public class ChatHub:Hub
    {
        public async Task SendMessage(string user,string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }

可以看到这里是调用了Clients.All.SendAsync方法。我们查看源码,可以看到Hub是一个抽象类

public abstract class Hub : IDisposable
    {
        private bool _disposed;
        private IHubCallerClients _clients;
        private HubCallerContext _context;
        private IGroupManager _groups;

        /// <summary>
        /// Gets or sets an object that can be used to invoke methods on the clients connected to this hub.
        /// </summary>
        public IHubCallerClients Clients
        {
            get
            {
                CheckDisposed();
                return _clients;
            }
            set
            {
                CheckDisposed();
                _clients = value;
            }
        }
}

在Hub中的Clients继承IHubCallerClients的。我们通过Crtl+F12查看实现找到HubCallerClients。所以不难看出上文中的Clients其实是HubCallerClients对象。在HubCallerClients中可以找到这段代码

public IClientProxy All => _hubClients.All;
而这个_hubClients其实是HubClients。在HubClients的构造函数中我们可以看到
public HubClients(HubLifetimeManager<THub> lifetimeManager)
        {
            _lifetimeManager = lifetimeManager;
            All = new AllClientProxy<THub>(_lifetimeManager);
        }
HubLifetimeManager是一个抽象类。在这里我们用Redis做底板的时候。在这段代码里就完成了
HubLifetimeManager的注册
public static ISignalRServerBuilder AddStackExchangeRedis(this ISignalRServerBuilder signalrBuilder, Action<RedisOptions> configure)
        {
            signalrBuilder.Services.Configure(configure);
            signalrBuilder.Services.AddSingleton(typeof(HubLifetimeManager<>), typeof(RedisHubLifetimeManager<>));
            return signalrBuilder;
        }

而这个AllClientProxy对象其实很干净。只有一个方法

internal class AllClientProxy<THub> : IClientProxy where THub : Hub
    {
        private readonly HubLifetimeManager<THub> _lifetimeManager;

        public AllClientProxy(HubLifetimeManager<THub> lifetimeManager)
        {
            _lifetimeManager = lifetimeManager;
        }

        public Task SendCoreAsync(string method, object[] args, CancellationToken cancellationToken = default)
        {
            return _lifetimeManager.SendAllAsync(method, args);
        }
    }

所以上面的Clients.All其实是AllClientProxy对象。至于SendAsync其实是一个扩展方法

public static Task SendAsync(this IClientProxy clientProxy, string method, object arg1, object arg2, CancellationToken cancellationToken = default)
        {
            return clientProxy.SendCoreAsync(method, new[] { arg1, arg2 }, cancellationToken);
        }

可以看到,此时Clients.All.SendAsync实际上是调用AllClientProxy的SendCoreAsync方法

posted @ 2019-08-21 16:55  独特的坏  阅读(1729)  评论(0编辑  收藏  举报