123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- //
- // NTESSubscribeManager.m
- // NIM
- //
- // Created by chris on 2017/4/5.
- // Copyright © 2017年 Netease. All rights reserved.
- //
- #import "NTESSubscribeManager.h"
- #import "NTESSubscribeDefine.h"
- #import "NTESDevice.h"
- #import "NIMExtensionHelper.h"
- #define NTESSubscribeExpiry 60 * 60 * 24 * 1 //订阅有效期为 1 天
- #define NTESSubscribeEnable [NIMSDK sharedSDK].isUsingDemoAppKey //仅在使用 Demo App 的时候,将订阅能力开启,开发者可以根据自身应用订阅功能开启状态控制此开关。
- NSString *const NTESSubscribeNetState = @"net_state";
- NSString *const NTESSubscribeOnlineState = @"online_state";
- @interface NTESSubscribeManager()<NIMEventSubscribeManagerDelegate,NIMConversationManagerDelegate,NIMLoginManagerDelegate,NIMUserManagerDelegate>
- @property (nonatomic,strong) NSMutableDictionary *events;
- @property (nonatomic,strong) NSMutableSet *subscribeIds;
- @property (nonatomic,strong) NSMutableSet *tempSubscribeIds;
- @end
- @implementation NTESSubscribeManager
- + (instancetype)sharedManager
- {
- if (NTESSubscribeEnable)
- {
- static NTESSubscribeManager *instance;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [[NTESSubscribeManager alloc] init];
- });
- return instance;
- }
- else
- {
- return nil;
- }
- }
- - (instancetype)init
- {
- self = [super init];
- if (self)
- {
- _events = [[NSMutableDictionary alloc] init];
- _subscribeIds = [[NSMutableSet alloc] init];
- _tempSubscribeIds = [[NSMutableSet alloc] init];
- [[NIMSDK sharedSDK].subscribeManager addDelegate:self];
- [[NIMSDK sharedSDK].conversationManager addDelegate:self];
- [[NIMSDK sharedSDK].loginManager addDelegate:self];
- [[NIMSDK sharedSDK].userManager addDelegate:self];
- }
- return self;
- }
- - (void)start
- {
- DDLogInfo(@"SubscribeManager Center Setup");
- }
- - (void)dealloc
- {
- [[NIMSDK sharedSDK].subscribeManager removeDelegate:self];
- [[NIMSDK sharedSDK].conversationManager removeDelegate:self];
- [[NIMSDK sharedSDK].userManager removeDelegate:self];
- }
- - (NSDictionary<NIMSubscribeEvent *,NSString *> *)eventsForType:(NSInteger)type
- {
- return [self.events objectForKey:@(type)];
- }
- - (void)subscribeTempUserOnlineState:(NSString *)userId
- {
- BOOL isRobot = [[NIMSDK sharedSDK].robotManager isValidRobot:userId];
- BOOL isMe = [[NIMSDK sharedSDK].loginManager.currentAccount isEqualToString:userId];
- if (isRobot || isMe) {
- DDLogInfo(@"user can not subscribe temp publisher: %@",userId);
- //自己或者机器人,则不需要订阅
- return;
- }
- NIMSubscribeRequest *request = [self generateRequest];
- request.publishers = @[userId];
- [self.tempSubscribeIds addObject:userId];
- [[NIMSDK sharedSDK].subscribeManager subscribeEvent:request completion:^(NSError * _Nullable error, NSArray * _Nullable failedPublishers) {
- DDLogInfo(@"subscribe temp publisher:%@ error: %@ failed publishers: %@",request.publishers,error,failedPublishers);
- }];
- }
- - (void)unsubscribeTempUserOnlineState:(NSString *)userId
- {
- if (![_subscribeIds containsObject:userId])
- {
- //如果这个人没有订阅
- NIMSubscribeRequest *request = [self generateRequest];
- request.publishers = @[userId];
- [[NIMSDK sharedSDK].subscribeManager unSubscribeEvent:request completion:^(NSError * _Nullable error, NSArray * _Nullable failedPublishers) {
- DDLogInfo(@"unSubscribe temp publisher:%@ error: %@ failed publishers: %@",request.publishers,error,failedPublishers);
- }];
- [self.tempSubscribeIds removeObject:userId];
- }
- }
- - (void)cleanCache
- {
- [_subscribeIds removeAllObjects];
- [_tempSubscribeIds removeAllObjects];
- [_events removeAllObjects];
- }
- - (void)publishOnlineState
- {
- NIMSubscribeEvent *event = [[NIMSubscribeEvent alloc] init];
- event.type = NIMSubscribeSystemEventTypeOnline;
- event.value = NTESCustomStateValueOnlineExt;
- event.sendToOnlineUsersOnly = NO; //必须要让后登录的用户也能拿到
- NSDictionary *ext = @{
- NTESSubscribeNetState : @([NTESDevice currentDevice].currentNetworkType),
- NTESSubscribeOnlineState : @(NTESOnlineStateNormal), //移动端永远在线
- };
- [event setExt:[ext nimkit_jsonString]];
- [[NIMSDK sharedSDK].subscribeManager publishEvent:event completion:^(NSError * _Nullable error, NIMSubscribeEvent * _Nullable event) {
- DDLogInfo(@"publish online state error %@ ext %@ time %.2f",error,ext,event.timestamp);
- }];
- }
- - (void)subscribeOnlineState
- {
- [_subscribeIds addObjectsFromArray:self.recentSessionUserIds.allObjects];
- [_subscribeIds addObjectsFromArray:self.contactUserIds.allObjects];
-
- [self subscribeNextMembers:_subscribeIds.allObjects];
- }
- - (void)subscribeNextMembers:(NSArray *)ids
- {
- if (!ids.count) {
- return;
- }
- NIMSubscribeRequest *request = [self generateRequest];
- NSInteger maxRequestCount = 100;
- NSArray *publishers;
- NSRange remove = ids.count > maxRequestCount? NSMakeRange(0, maxRequestCount): NSMakeRange(0, ids.count);
- publishers = [ids subarrayWithRange:remove];
-
- request.publishers = publishers;
-
- __weak typeof(self) weakSelf = self;
- [[NIMSDK sharedSDK].subscribeManager subscribeEvent:request completion:^(NSError * _Nullable error, NSArray * _Nullable failedPublishers) {
- DDLogInfo(@"subscribe publisher:%@ error: %@ failed publishers: %@",request.publishers,error,failedPublishers);
- NSMutableArray *members = [ids mutableCopy];
- [members removeObjectsInRange:remove];
- if (members.count) {
- [weakSelf subscribeNextMembers:members];
- }
- }];
- }
- #pragma mark - NIMLoginManagerDelegate
- - (void)onLogin:(NIMLoginStep)step
- {
- if (step == NIMLoginStepLinking)
- {
- [self cleanCache];
- }
- if (step == NIMLoginStepSyncOK)
- {
- [self publishOnlineState];
- [self subscribeOnlineState];
- }
- }
- #pragma mark - NIMUserManagerDelegate
- - (void)onFriendChanged:(NIMUser *)user
- {
- BOOL isMyFriend = [[NIMSDK sharedSDK].userManager isMyFriend:user.userId];
- if (isMyFriend && ![self.subscribeIds containsObject:user.userId])
- {
- //是好友却没订阅,订阅一下
- NIMSubscribeRequest *request = [self generateRequest];
- request.publishers = @[user.userId];
- [[NIMSDK sharedSDK].subscribeManager subscribeEvent:request completion:^(NSError * _Nullable error, NSArray * _Nullable failedPublishers) {
- if (!error) {
- [self.subscribeIds addObject:user.userId];
- }
- DDLogInfo(@"subscribe publisher: %@ error: %@",request.publishers,error);
- }];
- }
- if (!isMyFriend && ![self.recentSessionUserIds containsObject:user.userId]) {
- //不再是好友,从订阅集里删掉,等到下次服务器下发订阅事件,再反订阅即可
- [self.subscribeIds removeObject:user.userId];
- }
- }
- #pragma mark - NIMEventSubscribeManagerDelegate
- - (void)onRecvSubscribeEvents:(NSArray *)events
- {
- NSMutableArray *unSubscribeUsers = [[NSMutableArray alloc] init];
- for (NIMSubscribeEvent *event in events) {
- if ([self.subscribeIds containsObject:event.from] || [self.tempSubscribeIds containsObject:event.from])
- {
- NSInteger type = event.type;
- NSMutableDictionary *eventsDict = [self.events objectForKey:@(type)];
- if (!eventsDict) {
- eventsDict = [[NSMutableDictionary alloc] init];
- [self.events setObject:eventsDict forKey:@(type)];
- }
- NIMSubscribeEvent *oldEvent = [eventsDict objectForKey:event.from];
- if (oldEvent.timestamp > event.timestamp)
- {
- //服务器不保证事件的顺序,如果发现是同类型的过期事件,根据自身业务情况决定是否过滤。
- DDLogInfo(@"event id %@ from %@ is out of date, ingore...",event.eventId,event.from);
- }
- else
- {
- [eventsDict setObject:event forKey:event.from];
- DDLogInfo(@"receive event id %@ from %@ time %.2f",event.eventId,event.from,event.timestamp);
- }
-
- }
- else
- {
- //删掉了或者是以前订阅的没有干掉,这里反订阅一下
- [unSubscribeUsers addObject:event.from];
- }
- }
-
- //反订阅
- if (unSubscribeUsers.count)
- {
- NIMSubscribeRequest *request = [self generateRequest];
- request.publishers = [NSArray arrayWithArray:unSubscribeUsers];
- [[NIMSDK sharedSDK].subscribeManager unSubscribeEvent:request completion:^(NSError * _Nullable error, NSArray * _Nullable failedPublishers) {
- DDLogInfo(@"unSubscribe publisher:%@ error: %@ failed publishers: %@",request.publishers,error,failedPublishers);
- }];
- }
- }
- #pragma mark - NIMConversationManagerDelegate
- - (void)didAddRecentSession:(NIMRecentSession *)recentSession
- totalUnreadCount:(NSInteger)totalUnreadCount
- {
- if (recentSession.session.sessionType == NIMSessionTypeP2P) {
- [self.subscribeIds addObject:recentSession.session.sessionId];
-
- NIMSubscribeRequest *request = [self generateRequest];
- request.publishers = @[recentSession.session.sessionId];
- [[NIMSDK sharedSDK].subscribeManager subscribeEvent:request completion:^(NSError * _Nullable error, NSArray * _Nullable failedPublishers) {
- DDLogInfo(@"subscribe publisher: %@ error: %@",request.publishers,error);
- }];
- }
- }
- - (void)didRemoveRecentSession:(NIMRecentSession *)recentSession
- totalUnreadCount:(NSInteger)totalUnreadCount
- {
- if (recentSession.session.sessionType == NIMSessionTypeP2P && ![self.contactUserIds containsObject:recentSession.session.sessionId]) {
- [self.subscribeIds removeObject:recentSession.session.sessionId];
- }
- }
- #pragma mark - Private
- - (NIMSubscribeRequest *)generateRequest
- {
- NIMSubscribeRequest *request = [[NIMSubscribeRequest alloc] init];
- request.type = NIMSubscribeSystemEventTypeOnline;
- request.expiry = NTESSubscribeExpiry;
- request.syncEnabled = YES;
- return request;
- }
- - (NSSet *)recentSessionUserIds
- {
- NSMutableSet *ids = [[NSMutableSet alloc] init];
- NSString *me = [NIMSDK sharedSDK].loginManager.currentAccount;
- for (NIMRecentSession *recent in [NIMSDK sharedSDK].conversationManager.allRecentSessions) {
- BOOL isRobot = [[NIMSDK sharedSDK].robotManager isValidRobot:recent.session.sessionId];
- if (recent.session.sessionType == NIMSessionTypeP2P && !isRobot && ![recent.session.sessionId isEqualToString:me])
- {
- [ids addObject:recent.session.sessionId];
- }
- }
- return [NSSet setWithSet:ids];
- }
- - (NSSet *)contactUserIds
- {
- NSMutableSet *ids = [[NSMutableSet alloc] init];
- for (NIMUser *user in [NIMSDK sharedSDK].userManager.myFriends) {
- [ids addObject:user.userId];
- }
- return [NSSet setWithSet:ids];
- }
- @end
|