.NET Core SignalR Redis底板详解(二)
接上文。
上文說(shuō)到Clients.All.SendAsync實(shí)際上是調(diào)用AllClientProxy的SendCoreAsync方法。其實(shí)主要是調(diào)用IClientProxy的SendCoreAsync。在上文說(shuō)到的HubClients類里。就有很多IClientProxy的實(shí)現(xiàn)類。比如剛剛說(shuō)到的All其實(shí)是AllClientProxy對(duì)象。
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);}這些實(shí)現(xiàn)類其實(shí)里面都是千篇一律的構(gòu)造函數(shù)和SendCoreAsync。真正起作用的還是HubLifetimeManager對(duì)象。上文中說(shuō)了。在AdRedis的時(shí)候就已經(jīng)把RedisHubLifetimeManager注入進(jìn)去了。所以這里其實(shí)真正調(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ā)送。(這段代碼太晦澀。我沒看懂,只是猜個(gè)大概)。在PublishAsync實(shí)現(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的訂閱。這個(gè)OnConnectedAsync方法在HubConnectionHandler中的OnConnectedAsync中被調(diào)用。從名字就可以看出來(lái)HubConnectionHandler是處理HubConnection的。而HubConnectionHandler的調(diào)用則是在我們一開始UseHub的時(shí)候。
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>>();}至此。整個(gè)廣播流程就講解完畢了。
這里說(shuō)一下為什么前言中的方法不好。因?yàn)橛媒涌诒┞兜男问狡鋵?shí)是走Http協(xié)議。而Redis的訂閱與發(fā)布是走RESP協(xié)議。Http是超文本傳輸協(xié)議在子房間多的情況下會(huì)額外用掉很多帶寬與IIS的處理資源。而且用Redis的訂閱發(fā)布模式,Channel的方式與Signalr的Group等其他方式的思路其實(shí)是相同的。
最后貼一下微軟的官方說(shuō)明。
設(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底板详解(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core SignalR Re
- 下一篇: .Net 零星小知识