.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方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM