.NET Core SignalR Redis底板详解(二)
接上文。
上文說到Clients.All.SendAsync實際上是調(diào)用AllClientProxy的SendCoreAsync方法。其實主要是調(diào)用IClientProxy的SendCoreAsync。在上文說到的HubClients類里。就有很多IClientProxy的實現(xiàn)類。比如剛剛說到的All其實是AllClientProxy對象。
public IClientProxy AllExcept(IReadOnlyList<string> excludedConnectionIds){return new AllClientsExceptProxy<THub>(_lifetimeManager, excludedConnectionIds);}public IClientProxy Client(string connectionId){return new SingleClientProxy<THub>(_lifetimeManager, connectionId);}public IClientProxy Group(string groupName){return new GroupProxy<THub>(_lifetimeManager, groupName);}public IClientProxy GroupExcept(string groupName, IReadOnlyList<string> excludedConnectionIds){return new GroupExceptProxy<THub>(_lifetimeManager, groupName, excludedConnectionIds);}public IClientProxy Clients(IReadOnlyList<string> connectionIds){return new MultipleClientProxy<THub>(_lifetimeManager, connectionIds);}public IClientProxy Groups(IReadOnlyList<string> groupNames){return new MultipleGroupProxy<THub>(_lifetimeManager, groupNames);}public IClientProxy User(string userId){return new UserProxy<THub>(_lifetimeManager, userId);}public IClientProxy Users(IReadOnlyList<string> userIds){return new MultipleUserProxy<THub>(_lifetimeManager, userIds);}這些實現(xiàn)類其實里面都是千篇一律的構(gòu)造函數(shù)和SendCoreAsync。真正起作用的還是HubLifetimeManager對象。上文中說了。在AdRedis的時候就已經(jīng)把RedisHubLifetimeManager注入進(jìn)去了。所以這里其實真正調(diào)用的還是RedisHubLifetimeManager中的SendAllAsync方法。
public override Task SendAllAsync(string methodName, object[] args, CancellationToken cancellationToken = default){var message = _protocol.WriteInvocation(methodName, args);return PublishAsync(_channels.All, message);}在WriteInvocation方法中完成廣播的發(fā)送。(這段代碼太晦澀。我沒看懂,只是猜個大概)。在PublishAsync實現(xiàn)的是Redis的推送。
那么其他服務(wù)器是怎么收到廣播的呢?
同樣是在RedisHubLifetimeManager中。重寫了OnConnectedAsync方法。
public override async Task OnConnectedAsync(HubConnectionContext connection){await EnsureRedisServerConnection();var feature = new RedisFeature();connection.Features.Set<IRedisFeature>(feature);var connectionTask = Task.CompletedTask;var userTask = Task.CompletedTask;_connections.Add(connection);connectionTask = SubscribeToConnection(connection);if (!string.IsNullOrEmpty(connection.UserIdentifier)){userTask = SubscribeToUser(connection);}await Task.WhenAll(connectionTask, userTask);}在這里通過SubscribeToConnection方法完成了Redis的訂閱。這個OnConnectedAsync方法在HubConnectionHandler中的OnConnectedAsync中被調(diào)用。從名字就可以看出來HubConnectionHandler是處理HubConnection的。而HubConnectionHandler的調(diào)用則是在我們一開始UseHub的時候。
public static IConnectionBuilder UseHub<THub>(this IConnectionBuilder connectionBuilder) where THub : Hub{var marker = connectionBuilder.ApplicationServices.GetService(typeof(SignalRCoreMarkerService));if (marker == null){throw new InvalidOperationException("Unable to find the required services. Please add all the required services by calling " +"'IServiceCollection.AddSignalR' inside the call to 'ConfigureServices(...)' in the application startup code.");}return connectionBuilder.UseConnectionHandler<HubConnectionHandler<THub>>();}至此。整個廣播流程就講解完畢了。
這里說一下為什么前言中的方法不好。因為用接口暴露的形式其實是走Http協(xié)議。而Redis的訂閱與發(fā)布是走RESP協(xié)議。Http是超文本傳輸協(xié)議在子房間多的情況下會額外用掉很多帶寬與IIS的處理資源。而且用Redis的訂閱發(fā)布模式,Channel的方式與Signalr的Group等其他方式的思路其實是相同的。
最后貼一下微軟的官方說明。
設(shè)置 ASP.NET Core SignalR 橫向擴(kuò)展 Redis 底板
https://docs.microsoft.com/zh-cn/aspnet/core/signalr/redis-backplane?view=aspnetcore-2.2
教程:ASP.NET Core SignalR 入門
https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-2.2&tabs=visual-studio
轉(zhuǎn)載于:https://www.cnblogs.com/dbdn/p/11390928.html
總結(jié)
以上是生活随笔為你收集整理的.NET Core SignalR Redis底板详解(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core SignalR Re
- 下一篇: .Net 零星小知识