Create different externalSignalingController for each user.

Signed-off-by: Ivan Sein <ivan@nextcloud.com>
This commit is contained in:
Ivan Sein 2019-11-14 10:24:21 +01:00
Родитель 3f6f520c4b
Коммит 94edbbdd04
7 изменённых файлов: 165 добавлений и 117 удалений

Просмотреть файл

@ -28,7 +28,7 @@ static NSString * const kNCAudioTrackId = @"NCa0";
static NSString * const kNCVideoTrackId = @"NCv0"; static NSString * const kNCVideoTrackId = @"NCv0";
static NSString * const kNCVideoTrackKind = @"video"; static NSString * const kNCVideoTrackKind = @"video";
@interface NCCallController () <NCPeerConnectionDelegate, NCSignalingControllerObserver> @interface NCCallController () <NCPeerConnectionDelegate, NCSignalingControllerObserver, NCExternalSignalingControllerDelegate>
@property (nonatomic, assign) BOOL isAudioOnly; @property (nonatomic, assign) BOOL isAudioOnly;
@property (nonatomic, assign) BOOL inCall; @property (nonatomic, assign) BOOL inCall;
@ -49,6 +49,8 @@ static NSString * const kNCVideoTrackKind = @"video";
@property (nonatomic, strong) RTCVideoTrack *localVideoTrack; @property (nonatomic, strong) RTCVideoTrack *localVideoTrack;
@property (nonatomic, strong) RTCPeerConnectionFactory *peerConnectionFactory; @property (nonatomic, strong) RTCPeerConnectionFactory *peerConnectionFactory;
@property (nonatomic, strong) NCSignalingController *signalingController; @property (nonatomic, strong) NCSignalingController *signalingController;
@property (nonatomic, strong) NCExternalSignalingController *externalSignalingController;
@property (nonatomic, strong) TalkAccount *account;
@property (nonatomic, strong) NSURLSessionTask *joinCallTask; @property (nonatomic, strong) NSURLSessionTask *joinCallTask;
@property (nonatomic, strong) NSURLSessionTask *getPeersForCallTask; @property (nonatomic, strong) NSURLSessionTask *getPeersForCallTask;
@ -74,6 +76,10 @@ static NSString * const kNCVideoTrackKind = @"video";
_signalingController = [[NCSignalingController alloc] initForRoom:room]; _signalingController = [[NCSignalingController alloc] initForRoom:room];
_signalingController.observer = self; _signalingController.observer = self;
_account = [[NCDatabaseManager sharedInstance] activeAccount];
_externalSignalingController = [[NCSettingsController sharedInstance] externalSignalingControllerForAccount:_account.accountId];
_externalSignalingController.delegate = self;
if (audioOnly) { if (audioOnly) {
[[NCAudioController sharedInstance] setAudioSessionToVoiceChatMode]; [[NCAudioController sharedInstance] setAudioSessionToVoiceChatMode];
} else { } else {
@ -81,11 +87,6 @@ static NSString * const kNCVideoTrackKind = @"video";
} }
[self initRecorder]; [self initRecorder];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(externalSignalingMessageReceived:) name:NCESReceivedSignalingMessageNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(externalParticipantListMessageReceived:) name:NCESReceivedParticipantListMessageNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(shouldRejoinCall:) name:NCESShouldRejoinCallNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willRejoinCall:) name:NCESWillRejoinCallNotification object:nil];
} }
return self; return self;
@ -99,14 +100,14 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)joinCall - (void)joinCall
{ {
_joinCallTask = [[NCAPIController sharedInstance] joinCall:_room.token forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSError *error) { _joinCallTask = [[NCAPIController sharedInstance] joinCall:_room.token forAccount:_account withCompletionBlock:^(NSError *error) {
if (!error) { if (!error) {
[self.delegate callControllerDidJoinCall:self]; [self.delegate callControllerDidJoinCall:self];
[self getPeersForCall]; [self getPeersForCall];
[self startMonitoringMicrophoneAudioLevel]; [self startMonitoringMicrophoneAudioLevel];
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { if ([_externalSignalingController isEnabled]) {
_userSessionId = [[NCExternalSignalingController sharedInstance] sessionId]; _userSessionId = [_externalSignalingController sessionId];
if ([[NCExternalSignalingController sharedInstance] hasMCU]) { if ([_externalSignalingController hasMCU]) {
[self createOwnPublishPeerConnection]; [self createOwnPublishPeerConnection];
} }
if (_pendingUsersInRoom) { if (_pendingUsersInRoom) {
@ -132,14 +133,14 @@ static NSString * const kNCVideoTrackKind = @"video";
}]; }];
} }
- (void)shouldRejoinCall:(NSNotification *)notification - (void)shouldRejoinCall
{ {
_userSessionId = [[NCExternalSignalingController sharedInstance] sessionId]; _userSessionId = [_externalSignalingController sessionId];
_joinCallTask = [[NCAPIController sharedInstance] joinCall:_room.token forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSError *error) { _joinCallTask = [[NCAPIController sharedInstance] joinCall:_room.token forAccount:_account withCompletionBlock:^(NSError *error) {
if (!error) { if (!error) {
[self.delegate callControllerDidJoinCall:self]; [self.delegate callControllerDidJoinCall:self];
NSLog(@"Rejoined call"); NSLog(@"Rejoined call");
if ([[NCExternalSignalingController sharedInstance] hasMCU]) { if ([_externalSignalingController hasMCU]) {
[self createOwnPublishPeerConnection]; [self createOwnPublishPeerConnection];
} }
if (_pendingUsersInRoom) { if (_pendingUsersInRoom) {
@ -155,7 +156,7 @@ static NSString * const kNCVideoTrackKind = @"video";
}]; }];
} }
- (void)willRejoinCall:(NSNotification *)notification - (void)willRejoinCall
{ {
NSLog(@"willRejoinCall"); NSLog(@"willRejoinCall");
[self setInCall:NO]; [self setInCall:NO];
@ -170,7 +171,7 @@ static NSString * const kNCVideoTrackKind = @"video";
[self setInCall:NO]; [self setInCall:NO];
[self cleanCurrentPeerConnections]; [self cleanCurrentPeerConnections];
[self.delegate callControllerIsReconnectingCall:self]; [self.delegate callControllerIsReconnectingCall:self];
[[NCExternalSignalingController sharedInstance] forceReconnect]; [_externalSignalingController forceReconnect];
} }
- (void)leaveCall - (void)leaveCall
@ -344,7 +345,7 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)getPeersForCall - (void)getPeersForCall
{ {
_getPeersForCallTask = [[NCAPIController sharedInstance] getPeersForCall:_room.token forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSMutableArray *peers, NSError *error) { _getPeersForCallTask = [[NCAPIController sharedInstance] getPeersForCall:_room.token forAccount:_account withCompletionBlock:^(NSMutableArray *peers, NSError *error) {
if (!error) { if (!error) {
_peersInCall = peers; _peersInCall = peers;
} }
@ -405,7 +406,7 @@ static NSString * const kNCVideoTrackKind = @"video";
peerConnectionWrapper.roomType = roomType; peerConnectionWrapper.roomType = roomType;
peerConnectionWrapper.delegate = self; peerConnectionWrapper.delegate = self;
// TODO: Try to get display name here // TODO: Try to get display name here
if (![[NCExternalSignalingController sharedInstance] hasMCU] || !screensharingPeer) { if (![_externalSignalingController hasMCU] || !screensharingPeer) {
[peerConnectionWrapper.peerConnection addStream:_localStream]; [peerConnectionWrapper.peerConnection addStream:_localStream];
} }
@ -434,7 +435,7 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)sendDataChannelMessageToAllOfType:(NSString *)type withPayload:(id)payload - (void)sendDataChannelMessageToAllOfType:(NSString *)type withPayload:(id)payload
{ {
if ([[NCExternalSignalingController sharedInstance] hasMCU]) { if ([_externalSignalingController hasMCU]) {
[_ownPeerConnection sendDataChannelMessageOfType:type withPayload:payload]; [_ownPeerConnection sendDataChannelMessageOfType:type withPayload:payload];
} else { } else {
NSArray *connectionWrappers = [self.connectionsDict allValues]; NSArray *connectionWrappers = [self.connectionsDict allValues];
@ -459,33 +460,11 @@ static NSString * const kNCVideoTrackKind = @"video";
[_ownPeerConnection sendPublishOfferToMCU]; [_ownPeerConnection sendPublishOfferToMCU];
} }
- (void)externalSignalingMessageReceived:(NSNotification *)notification
{
NSLog(@"External signaling message received: %@", notification);
NCSignalingMessage *signalingMessage = [NCSignalingMessage messageFromExternalSignalingJSONDictionary:notification.userInfo];
[self checkIfPendingOffer:signalingMessage];
[self processSignalingMessage:signalingMessage];
}
- (void)externalParticipantListMessageReceived:(NSNotification *)notification
{
NSLog(@"External participants message received: %@", notification);
NSArray *usersInRoom = [notification.userInfo objectForKey:@"users"];
if (_inCall) {
[self processUsersInRoom:usersInRoom];
} else {
// Store pending usersInRoom since this websocket message could
// arrive before NCCallController knows that it's in the call.
_pendingUsersInRoom = usersInRoom;
}
}
- (void)sendNick - (void)sendNick
{ {
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
NSDictionary *payload = @{ NSDictionary *payload = @{
@"userid":activeAccount.userId, @"userid":_account.userId,
@"name":activeAccount.userDisplayName @"name":_account.userDisplayName
}; };
[self sendDataChannelMessageToAllOfType:@"nickChanged" withPayload:payload]; [self sendDataChannelMessageToAllOfType:@"nickChanged" withPayload:payload];
} }
@ -509,7 +488,7 @@ static NSString * const kNCVideoTrackKind = @"video";
{ {
NSString *sessionId = [timer.userInfo objectForKey:@"sessionId"]; NSString *sessionId = [timer.userInfo objectForKey:@"sessionId"];
NSString *roomType = [timer.userInfo objectForKey:@"roomType"]; NSString *roomType = [timer.userInfo objectForKey:@"roomType"];
[[NCExternalSignalingController sharedInstance] requestOfferForSessionId:sessionId andRoomType:roomType]; [_externalSignalingController requestOfferForSessionId:sessionId andRoomType:roomType];
} }
- (void)checkIfPendingOffer:(NCSignalingMessage *)signalingMessage - (void)checkIfPendingOffer:(NCSignalingMessage *)signalingMessage
@ -521,6 +500,39 @@ static NSString * const kNCVideoTrackKind = @"video";
} }
} }
#pragma mark - External Signaling Controller Delegate
- (void)externalSignalingController:(NCExternalSignalingController *)externalSignalingController didReceivedSignalingMessage:(NSDictionary *)signalingMessageDict
{
NSLog(@"External signaling message received: %@", signalingMessageDict);
NCSignalingMessage *signalingMessage = [NCSignalingMessage messageFromExternalSignalingJSONDictionary:signalingMessageDict];
[self checkIfPendingOffer:signalingMessage];
[self processSignalingMessage:signalingMessage];
}
- (void)externalSignalingController:(NCExternalSignalingController *)externalSignalingController didReceivedParticipantListMessage:(NSDictionary *)participantListMessageDict
{
NSLog(@"External participants message received: %@", participantListMessageDict);
NSArray *usersInRoom = [participantListMessageDict objectForKey:@"users"];
if (_inCall) {
[self processUsersInRoom:usersInRoom];
} else {
// Store pending usersInRoom since this websocket message could
// arrive before NCCallController knows that it's in the call.
_pendingUsersInRoom = usersInRoom;
}
}
- (void)externalSignalingControllerShouldRejoinCall:(NCExternalSignalingController *)externalSignalingController
{
[self shouldRejoinCall];
}
- (void)externalSignalingControllerWillRejoinCall:(NCExternalSignalingController *)externalSignalingController
{
[self willRejoinCall];
}
#pragma mark - Signaling Controller Delegate #pragma mark - Signaling Controller Delegate
- (void)signalingController:(NCSignalingController *)signalingController didReceiveSignalingMessage:(NSDictionary *)message - (void)signalingController:(NCSignalingController *)signalingController didReceiveSignalingMessage:(NSDictionary *)message
@ -604,9 +616,9 @@ static NSString * const kNCVideoTrackKind = @"video";
for (NSString *sessionId in newSessions) { for (NSString *sessionId in newSessions) {
NSString *peerKey = [sessionId stringByAppendingString:kRoomTypeVideo]; NSString *peerKey = [sessionId stringByAppendingString:kRoomTypeVideo];
if (![_connectionsDict objectForKey:peerKey] && ![_userSessionId isEqualToString:sessionId]) { if (![_connectionsDict objectForKey:peerKey] && ![_userSessionId isEqualToString:sessionId]) {
if ([[NCExternalSignalingController sharedInstance] hasMCU]) { if ([_externalSignalingController hasMCU]) {
NSLog(@"Requesting offer to the MCU for session: %@", sessionId); NSLog(@"Requesting offer to the MCU for session: %@", sessionId);
[[NCExternalSignalingController sharedInstance] requestOfferForSessionId:sessionId andRoomType:kRoomTypeVideo]; [_externalSignalingController requestOfferForSessionId:sessionId andRoomType:kRoomTypeVideo];
} else { } else {
NSComparisonResult result = [sessionId compare:_userSessionId]; NSComparisonResult result = [sessionId compare:_userSessionId];
if (result == NSOrderedAscending) { if (result == NSOrderedAscending) {
@ -642,8 +654,8 @@ static NSString * const kNCVideoTrackKind = @"video";
- (NSString *)getUserIdFromSessionId:(NSString *)sessionId - (NSString *)getUserIdFromSessionId:(NSString *)sessionId
{ {
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { if ([_externalSignalingController isEnabled]) {
return [[NCExternalSignalingController sharedInstance] getUserIdFromSessionId:sessionId]; return [_externalSignalingController getUserIdFromSessionId:sessionId];
} }
NSString *userId = nil; NSString *userId = nil;
for (NSMutableDictionary *user in _peersInCall) { for (NSMutableDictionary *user in _peersInCall) {
@ -657,7 +669,7 @@ static NSString * const kNCVideoTrackKind = @"video";
- (void)getUserIdInServerFromSessionId:(NSString *)sessionId withCompletionBlock:(GetUserIdForSessionIdCompletionBlock)block - (void)getUserIdInServerFromSessionId:(NSString *)sessionId withCompletionBlock:(GetUserIdForSessionIdCompletionBlock)block
{ {
[[NCAPIController sharedInstance] getPeersForCall:_room.token forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSMutableArray *peers, NSError *error) { [[NCAPIController sharedInstance] getPeersForCall:_room.token forAccount:_account withCompletionBlock:^(NSMutableArray *peers, NSError *error) {
if (!error) { if (!error) {
NSString *userId = nil; NSString *userId = nil;
for (NSMutableDictionary *user in peers) { for (NSMutableDictionary *user in peers) {
@ -698,7 +710,7 @@ static NSString * const kNCVideoTrackKind = @"video";
if (peerConnection.isMCUPublisherPeer) { if (peerConnection.isMCUPublisherPeer) {
[self forceReconnect]; [self forceReconnect];
// If another peer failed using MCU then request a new offer // If another peer failed using MCU then request a new offer
} else if ([[NCExternalSignalingController sharedInstance] hasMCU]) { } else if ([_externalSignalingController hasMCU]) {
NSString *sessionId = [peerConnection.peerId copy]; NSString *sessionId = [peerConnection.peerId copy];
NSString *roomType = [peerConnection.roomType copy]; NSString *roomType = [peerConnection.roomType copy];
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
@ -707,7 +719,7 @@ static NSString * const kNCVideoTrackKind = @"video";
// Close failed peer connection // Close failed peer connection
[self cleanPeerConnectionsForSessionId:peerConnection.peerId]; [self cleanPeerConnectionsForSessionId:peerConnection.peerId];
// Request new offer // Request new offer
[[NCExternalSignalingController sharedInstance] requestOfferForSessionId:peerConnection.peerId andRoomType:peerConnection.roomType]; [_externalSignalingController requestOfferForSessionId:peerConnection.peerId andRoomType:peerConnection.roomType];
// Set timeout to request new offer // Set timeout to request new offer
NSTimer *pendingOfferTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(requestNewOffer:) userInfo:userInfo repeats:YES]; NSTimer *pendingOfferTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(requestNewOffer:) userInfo:userInfo repeats:YES];
[_pendingOffersDict setObject:pendingOfferTimer forKey:peerConnection.peerId]; [_pendingOffersDict setObject:pendingOfferTimer forKey:peerConnection.peerId];
@ -750,8 +762,8 @@ static NSString * const kNCVideoTrackKind = @"video";
sid:nil sid:nil
roomType:peerConnection.roomType]; roomType:peerConnection.roomType];
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { if ([_externalSignalingController isEnabled]) {
[[NCExternalSignalingController sharedInstance] sendCallMessage:message]; [_externalSignalingController sendCallMessage:message];
} else { } else {
[_signalingController sendSignalingMessage:message]; [_signalingController sendSignalingMessage:message];
} }
@ -767,8 +779,8 @@ static NSString * const kNCVideoTrackKind = @"video";
roomType:peerConnection.roomType roomType:peerConnection.roomType
nick:_userDisplayName]; nick:_userDisplayName];
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { if ([_externalSignalingController isEnabled]) {
[[NCExternalSignalingController sharedInstance] sendCallMessage:message]; [_externalSignalingController sendCallMessage:message];
} else { } else {
[_signalingController sendSignalingMessage:message]; [_signalingController sendSignalingMessage:message];
} }

Просмотреть файл

@ -12,7 +12,6 @@
#import "NCAPIController.h" #import "NCAPIController.h"
#import "NCDatabaseManager.h" #import "NCDatabaseManager.h"
#import "NCSettingsController.h" #import "NCSettingsController.h"
#import "NCExternalSignalingController.h"
#import "NCUserInterfaceController.h" #import "NCUserInterfaceController.h"
NSString * const NCAppStateHasChangedNotification = @"NCAppStateHasChangedNotification"; NSString * const NCAppStateHasChangedNotification = @"NCAppStateHasChangedNotification";
@ -88,9 +87,9 @@ NSString * const NCConnectionStateHasChangedNotification = @"NCConnectionStat
- (void)checkAppState - (void)checkAppState
{ {
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount]; TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
ServerCapabilities *serverCapabilities = [[NCDatabaseManager sharedInstance] serverCapabilitiesForAccountId:activeAccount.accountId]; ServerCapabilities *serverCapabilities = [[NCDatabaseManager sharedInstance] serverCapabilitiesForAccountId:activeAccount.accountId];
NSDictionary *ncSignalingConfig = [NCSettingsController sharedInstance].ncSignalingConfiguration; NSDictionary *activeAccountSignalingConfig = [[[NCSettingsController sharedInstance] signalingConfigutations] objectForKey:activeAccount.accountId];
if (!activeAccount.server || !activeAccount.user) { if (!activeAccount.server || !activeAccount.user) {
[self setAppState:kAppStateNotServerProvided]; [self setAppState:kAppStateNotServerProvided];
@ -113,14 +112,14 @@ NSString * const NCConnectionStateHasChangedNotification = @"NCConnectionStat
[self checkAppState]; [self checkAppState];
} }
}]; }];
} else if (!ncSignalingConfig) { } else if (!activeAccountSignalingConfig) {
[self setAppState:kAppStateMissingSignalingConfiguration]; [self setAppState:kAppStateMissingSignalingConfiguration];
[[NCSettingsController sharedInstance] getSignalingConfigurationWithCompletionBlock:^(NSError *error) { [[NCSettingsController sharedInstance] getSignalingConfigurationWithCompletionBlock:^(NSError *error) {
if (error) { if (error) {
[self notifyAppState]; [self notifyAppState];
} else { } else {
// SetSignalingConfiguration should be called just once // SetSignalingConfiguration should be called just once
[[NCSettingsController sharedInstance] setSignalingConfiguration]; [[NCSettingsController sharedInstance] setSignalingConfigurationForAccount:activeAccount.accountId];
[self checkAppState]; [self checkAppState];
} }
}]; }];

Просмотреть файл

@ -10,20 +10,28 @@
#import "NCSignalingMessage.h" #import "NCSignalingMessage.h"
extern NSString * const NCESReceivedSignalingMessageNotification; @class NCExternalSignalingController;
extern NSString * const NCESReceivedParticipantListMessageNotification; @class TalkAccount;
extern NSString * const NCESShouldRejoinCallNotification;
extern NSString * const NCESWillRejoinCallNotification; @protocol NCExternalSignalingControllerDelegate <NSObject>
- (void)externalSignalingController:(NCExternalSignalingController *)externalSignalingController didReceivedSignalingMessage:(NSDictionary *)signalingMessageDict;
- (void)externalSignalingController:(NCExternalSignalingController *)externalSignalingController didReceivedParticipantListMessage:(NSDictionary *)participantListMessageDict;
- (void)externalSignalingControllerShouldRejoinCall:(NCExternalSignalingController *)externalSignalingController;
- (void)externalSignalingControllerWillRejoinCall:(NCExternalSignalingController *)externalSignalingController;
@end
@interface NCExternalSignalingController : NSObject @interface NCExternalSignalingController : NSObject
@property (nonatomic, strong) NSString* currentRoom; @property (nonatomic, strong) NSString *currentRoom;
@property (nonatomic, strong) TalkAccount *account;
@property (nonatomic, weak) id<NCExternalSignalingControllerDelegate> delegate;
+ (instancetype)sharedInstance; - (instancetype)initWithAccount:(TalkAccount *)account server:(NSString *)serverUrl andTicket:(NSString *)ticket;
- (BOOL)isEnabled; - (BOOL)isEnabled;
- (BOOL)hasMCU; - (BOOL)hasMCU;
- (NSString *)sessionId; - (NSString *)sessionId;
- (void)setServer:(NSString *)serverUrl andTicket:(NSString *)ticket;
- (void)joinRoom:(NSString *)roomId withSessionId:(NSString *)sessionId; - (void)joinRoom:(NSString *)roomId withSessionId:(NSString *)sessionId;
- (void)leaveRoom:(NSString *)roomId; - (void)leaveRoom:(NSString *)roomId;
- (void)sendCallMessage:(NCSignalingMessage *)message; - (void)sendCallMessage:(NCSignalingMessage *)message;

Просмотреть файл

@ -25,6 +25,8 @@ static NSTimeInterval kMaxReconnectInterval = 16;
@property (nonatomic, strong) NSString* ticket; @property (nonatomic, strong) NSString* ticket;
@property (nonatomic, strong) NSString* resumeId; @property (nonatomic, strong) NSString* resumeId;
@property (nonatomic, strong) NSString* sessionId; @property (nonatomic, strong) NSString* sessionId;
@property (nonatomic, strong) NSString* userId;
@property (nonatomic, strong) NSString* authenticationBackendUrl;
@property (nonatomic, assign) BOOL connected; @property (nonatomic, assign) BOOL connected;
@property (nonatomic, assign) BOOL mcuSupport; @property (nonatomic, assign) BOOL mcuSupport;
@property (nonatomic, strong) NSMutableDictionary* participantsMap; @property (nonatomic, strong) NSMutableDictionary* participantsMap;
@ -38,11 +40,6 @@ static NSTimeInterval kMaxReconnectInterval = 16;
@implementation NCExternalSignalingController @implementation NCExternalSignalingController
NSString * const NCESReceivedSignalingMessageNotification = @"NCESReceivedSignalingMessageNotification";
NSString * const NCESReceivedParticipantListMessageNotification = @"NCESReceivedParticipantListMessageNotification";
NSString * const NCESShouldRejoinCallNotification = @"NCESShouldRejoinCallNotification";
NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotification";
+ (NCExternalSignalingController *)sharedInstance + (NCExternalSignalingController *)sharedInstance
{ {
static dispatch_once_t once; static dispatch_once_t once;
@ -53,6 +50,18 @@ NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotificati
return sharedInstance; return sharedInstance;
} }
- (instancetype)initWithAccount:(TalkAccount *)account server:(NSString *)serverUrl andTicket:(NSString *)ticket
{
self = [super init];
if (self) {
_account = account;
_userId = _account.userId;
_authenticationBackendUrl = [[NCAPIController sharedInstance] authenticationBackendUrlForAccount:_account];
[self setServer:serverUrl andTicket:ticket];
}
return self;
}
- (BOOL)isEnabled - (BOOL)isEnabled
{ {
return (_serverUrl) ? YES : NO; return (_serverUrl) ? YES : NO;
@ -181,15 +190,14 @@ NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotificati
- (void)sendHello - (void)sendHello
{ {
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
NSDictionary *helloDict = @{ NSDictionary *helloDict = @{
@"type": @"hello", @"type": @"hello",
@"hello": @{ @"hello": @{
@"version": @"1.0", @"version": @"1.0",
@"auth": @{ @"auth": @{
@"url": [[NCAPIController sharedInstance] authenticationBackendUrlForAccount:activeAccount], @"url": _authenticationBackendUrl,
@"params": @{ @"params": @{
@"userid": activeAccount.userId, @"userid": _userId,
@"ticket": _ticket @"ticket": _ticket
} }
} }
@ -231,9 +239,7 @@ NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotificati
// Re-join if user was in a room // Re-join if user was in a room
if (_currentRoom && _sessionChanged) { if (_currentRoom && _sessionChanged) {
[[NSNotificationCenter defaultCenter] postNotificationName:NCESWillRejoinCallNotification [self.delegate externalSignalingControllerWillRejoinCall:self];
object:self
userInfo:nil];
[[NCRoomsManager sharedInstance] rejoinRoom:_currentRoom]; [[NCRoomsManager sharedInstance] rejoinRoom:_currentRoom];
} }
} }
@ -311,9 +317,7 @@ NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotificati
// Notify that session has change to rejoin the call if currently in a call // Notify that session has change to rejoin the call if currently in a call
if (_sessionChanged) { if (_sessionChanged) {
_sessionChanged = NO; _sessionChanged = NO;
[[NSNotificationCenter defaultCenter] postNotificationName:NCESShouldRejoinCallNotification [self.delegate externalSignalingControllerShouldRejoinCall:self];
object:self
userInfo:nil];
} }
} }
@ -341,8 +345,7 @@ NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotificati
if (!participantId || [participantId isEqualToString:@""]) { if (!participantId || [participantId isEqualToString:@""]) {
NSLog(@"Guest joined room."); NSLog(@"Guest joined room.");
} else { } else {
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount]; if ([participantId isEqualToString:_userId]) {
if ([participantId isEqualToString:activeAccount.userId]) {
NSLog(@"App user joined room."); NSLog(@"App user joined room.");
} else { } else {
[_participantsMap setObject:participant forKey:[participant objectForKey:@"sessionid"]]; [_participantsMap setObject:participant forKey:[participant objectForKey:@"sessionid"]];
@ -379,9 +382,7 @@ NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotificati
NSString *eventType = [eventDict objectForKey:@"type"]; NSString *eventType = [eventDict objectForKey:@"type"];
if ([eventType isEqualToString:@"update"]) { if ([eventType isEqualToString:@"update"]) {
NSLog(@"Participant list changed: %@", [eventDict objectForKey:@"update"]); NSLog(@"Participant list changed: %@", [eventDict objectForKey:@"update"]);
[[NSNotificationCenter defaultCenter] postNotificationName:NCESReceivedParticipantListMessageNotification [self.delegate externalSignalingController:self didReceivedParticipantListMessage:[eventDict objectForKey:@"update"]];
object:self
userInfo:[eventDict objectForKey:@"update"]];
} else { } else {
NSLog(@"Unknown room event: %@", eventDict); NSLog(@"Unknown room event: %@", eventDict);
} }
@ -390,9 +391,7 @@ NSString * const NCESWillRejoinCallNotification = @"NCESWillRejoinCallNotificati
- (void)messageReceived:(NSDictionary *)messageDict - (void)messageReceived:(NSDictionary *)messageDict
{ {
NSLog(@"Message received"); NSLog(@"Message received");
[[NSNotificationCenter defaultCenter] postNotificationName:NCESReceivedSignalingMessageNotification [self.delegate externalSignalingController:self didReceivedSignalingMessage:messageDict];
object:self
userInfo:messageDict];
} }
#pragma mark - SRWebSocketDelegate #pragma mark - SRWebSocketDelegate

Просмотреть файл

@ -84,9 +84,10 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
{ {
NSMutableDictionary *userInfo = [NSMutableDictionary new]; NSMutableDictionary *userInfo = [NSMutableDictionary new];
NCRoomController *roomController = [_activeRooms objectForKey:token]; NCRoomController *roomController = [_activeRooms objectForKey:token];
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
if (!roomController) { if (!roomController) {
_joiningRoom = token; _joiningRoom = token;
_joinRoomTask = [[NCAPIController sharedInstance] joinRoom:token forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSString *sessionId, NSError *error, NSInteger statusCode) { _joinRoomTask = [[NCAPIController sharedInstance] joinRoom:token forAccount:activeAccount withCompletionBlock:^(NSString *sessionId, NSError *error, NSInteger statusCode) {
if (!_joiningRoom) { if (!_joiningRoom) {
NSLog(@"Not joining the room any more. Ignore response."); NSLog(@"Not joining the room any more. Ignore response.");
return; return;
@ -98,8 +99,9 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
[_activeRooms setObject:controller forKey:token]; [_activeRooms setObject:controller forKey:token];
[_joinRoomAttempts removeObjectForKey:token]; [_joinRoomAttempts removeObjectForKey:token];
[userInfo setObject:controller forKey:@"roomController"]; [userInfo setObject:controller forKey:@"roomController"];
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { NCExternalSignalingController *extSignalingController = [[NCSettingsController sharedInstance] externalSignalingControllerForAccount:activeAccount.accountId];
[[NCExternalSignalingController sharedInstance] joinRoom:token withSessionId:sessionId]; if ([extSignalingController isEnabled]) {
[extSignalingController joinRoom:token withSessionId:sessionId];
} }
} else { } else {
NSInteger joinAttempts = [[_joinRoomAttempts objectForKey:token] integerValue]; NSInteger joinAttempts = [[_joinRoomAttempts objectForKey:token] integerValue];
@ -142,14 +144,16 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
- (void)rejoinRoom:(NSString *)token - (void)rejoinRoom:(NSString *)token
{ {
NCRoomController *roomController = [_activeRooms objectForKey:token]; NCRoomController *roomController = [_activeRooms objectForKey:token];
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
if (roomController) { if (roomController) {
_joiningRoom = [token copy]; _joiningRoom = [token copy];
_joinRoomTask = [[NCAPIController sharedInstance] joinRoom:token forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSString *sessionId, NSError *error, NSInteger statusCode) { _joinRoomTask = [[NCAPIController sharedInstance] joinRoom:token forAccount:activeAccount withCompletionBlock:^(NSString *sessionId, NSError *error, NSInteger statusCode) {
if (!error) { if (!error) {
roomController.userSessionId = sessionId; roomController.userSessionId = sessionId;
roomController.inChat = YES; roomController.inChat = YES;
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { NCExternalSignalingController *extSignalingController = [[NCSettingsController sharedInstance] externalSignalingControllerForAccount:activeAccount.accountId];
[[NCExternalSignalingController sharedInstance] joinRoom:token withSessionId:sessionId]; if ([extSignalingController isEnabled]) {
[extSignalingController joinRoom:token withSessionId:sessionId];
} }
} else { } else {
NSLog(@"Could not re-join room. Status code: %ld. Error: %@", (long)statusCode, error.description); NSLog(@"Could not re-join room. Status code: %ld. Error: %@", (long)statusCode, error.description);
@ -172,11 +176,13 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
[roomController stopRoomController]; [roomController stopRoomController];
[_activeRooms removeObjectForKey:token]; [_activeRooms removeObjectForKey:token];
[[NCAPIController sharedInstance] exitRoom:token forAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSError *error) { TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
[[NCAPIController sharedInstance] exitRoom:token forAccount:activeAccount withCompletionBlock:^(NSError *error) {
NSMutableDictionary *userInfo = [NSMutableDictionary new]; NSMutableDictionary *userInfo = [NSMutableDictionary new];
if (!error) { if (!error) {
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { NCExternalSignalingController *extSignalingController = [[NCSettingsController sharedInstance] externalSignalingControllerForAccount:activeAccount.accountId];
[[NCExternalSignalingController sharedInstance] leaveRoom:token]; if ([extSignalingController isEnabled]) {
[extSignalingController leaveRoom:token];
} }
} else { } else {
[userInfo setObject:error forKey:@"error"]; [userInfo setObject:error forKey:@"error"];
@ -256,10 +262,12 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
NCRoomController *roomController = [_activeRooms objectForKey:room.token]; NCRoomController *roomController = [_activeRooms objectForKey:room.token];
if (!roomController) { if (!roomController) {
// Workaround until external signaling supports multi-room // Workaround until external signaling supports multi-room
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
NSString *currentRoom = [NCExternalSignalingController sharedInstance].currentRoom; NCExternalSignalingController *extSignalingController = [[NCSettingsController sharedInstance] externalSignalingControllerForAccount:activeAccount.accountId];
if ([extSignalingController isEnabled]) {
NSString *currentRoom = extSignalingController.currentRoom;
if (![currentRoom isEqualToString:room.token]) { if (![currentRoom isEqualToString:room.token]) {
[NCExternalSignalingController sharedInstance].currentRoom = nil; extSignalingController.currentRoom = nil;
} }
} }
} }
@ -339,14 +347,15 @@ NSString * const NCRoomsManagerDidReceiveChatMessagesNotification = @"ChatMess
[_callViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve]; [_callViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
_callViewController.delegate = self; _callViewController.delegate = self;
// Workaround until external signaling supports multi-room // Workaround until external signaling supports multi-room
if ([[NCExternalSignalingController sharedInstance] isEnabled]) { NCExternalSignalingController *extSignalingController = [[NCSettingsController sharedInstance] externalSignalingControllerForAccount:activeAccount.accountId];
NSString *currentRoom = [NCExternalSignalingController sharedInstance].currentRoom; if ([extSignalingController isEnabled]) {
NSString *currentRoom = extSignalingController.currentRoom;
if (![currentRoom isEqualToString:room.token]) { if (![currentRoom isEqualToString:room.token]) {
[[NCUserInterfaceController sharedInstance] presentConversationsList]; [[NCUserInterfaceController sharedInstance] presentConversationsList];
if (currentRoom) { if (currentRoom) {
[self leaveChatInRoom:currentRoom]; [self leaveChatInRoom:currentRoom];
} }
[NCExternalSignalingController sharedInstance].currentRoom = nil; extSignalingController.currentRoom = nil;
} }
} }
[[NCUserInterfaceController sharedInstance] presentCallViewController:_callViewController]; [[NCUserInterfaceController sharedInstance] presentCallViewController:_callViewController];

Просмотреть файл

@ -58,6 +58,7 @@ typedef enum NCPreferredFileSorting {
NCModificationDateSorting NCModificationDateSorting
} NCPreferredFileSorting; } NCPreferredFileSorting;
@class NCExternalSignalingController;
@interface NCSettingsController : NSObject @interface NCSettingsController : NSObject
@ -76,8 +77,9 @@ typedef enum NCPreferredFileSorting {
@property (nonatomic, copy) NSString *ncUserPublicKey; @property (nonatomic, copy) NSString *ncUserPublicKey;
@property (nonatomic, copy) NSString *defaultBrowser; @property (nonatomic, copy) NSString *defaultBrowser;
@property (nonatomic, copy) NSMutableArray *supportedBrowsers; @property (nonatomic, copy) NSMutableArray *supportedBrowsers;
@property (nonatomic, copy) NSDictionary *ncSignalingConfiguration;
@property (nonatomic, copy) ARDSettingsModel *videoSettingsModel; @property (nonatomic, copy) ARDSettingsModel *videoSettingsModel;
@property (nonatomic, copy) NSMutableDictionary *signalingConfigutations; // accountId -> signalingConfigutation
@property (nonatomic, copy) NSMutableDictionary *externalSignalingControllers; // accountId -> externalSignalingController
+ (instancetype)sharedInstance; + (instancetype)sharedInstance;
- (void)setToken:(NSString *)token forAccount:(NSString *)account; - (void)setToken:(NSString *)token forAccount:(NSString *)account;
@ -93,7 +95,8 @@ typedef enum NCPreferredFileSorting {
- (void)logoutWithCompletionBlock:(LogoutCompletionBlock)block; - (void)logoutWithCompletionBlock:(LogoutCompletionBlock)block;
- (void)getCapabilitiesWithCompletionBlock:(GetCapabilitiesCompletionBlock)block; - (void)getCapabilitiesWithCompletionBlock:(GetCapabilitiesCompletionBlock)block;
- (void)getSignalingConfigurationWithCompletionBlock:(GetSignalingConfigCompletionBlock)block; - (void)getSignalingConfigurationWithCompletionBlock:(GetSignalingConfigCompletionBlock)block;
- (void)setSignalingConfiguration; - (void)setSignalingConfigurationForAccount:(NSString *)accountId;
- (NCExternalSignalingController *)externalSignalingControllerForAccount:(NSString *)accountId;
- (void)subscribeForPushNotificationsForAccount:(NSString *)account; - (void)subscribeForPushNotificationsForAccount:(NSString *)account;
- (BOOL)serverHasTalkCapability:(NSString *)capability; - (BOOL)serverHasTalkCapability:(NSString *)capability;
- (NSInteger)chatMaxLengthConfigCapability; - (NSInteger)chatMaxLengthConfigCapability;

Просмотреть файл

@ -87,6 +87,10 @@ NSString * const NCUserProfileImageUpdatedNotification = @"NCUserProfileImageUpd
_videoSettingsModel = [[ARDSettingsModel alloc] init]; _videoSettingsModel = [[ARDSettingsModel alloc] init];
_keychain = [UICKeyChainStore keyChainStoreWithService:@"com.nextcloud.Talk" _keychain = [UICKeyChainStore keyChainStoreWithService:@"com.nextcloud.Talk"
accessGroup:@"group.com.nextcloud.Talk"]; accessGroup:@"group.com.nextcloud.Talk"];
_signalingConfigutations = [NSMutableDictionary new];
_externalSignalingControllers = [NSMutableDictionary new];
[self readValuesFromKeyChain]; [self readValuesFromKeyChain];
[self configureDatabase]; [self configureDatabase];
[self configureDefaultBrowser]; [self configureDefaultBrowser];
@ -225,8 +229,6 @@ NSString * const NCUserProfileImageUpdatedNotification = @"NCUserProfileImageUpd
_ncDeviceSignature = nil; _ncDeviceSignature = nil;
_defaultBrowser = @"Safari"; _defaultBrowser = @"Safari";
_pushNotificationSubscribed = nil; _pushNotificationSubscribed = nil;
// Also remove values that are not stored in the keychain
_ncSignalingConfiguration = nil;
[_keychain removeItemForKey:kNCServerKey]; [_keychain removeItemForKey:kNCServerKey];
[_keychain removeItemForKey:kNCUserKey]; [_keychain removeItemForKey:kNCUserKey];
@ -285,7 +287,8 @@ NSString * const NCUserProfileImageUpdatedNotification = @"NCUserProfileImageUpd
} }
}]; }];
} }
[[NCExternalSignalingController sharedInstance] disconnect]; NCExternalSignalingController *extSignalingController = [self externalSignalingControllerForAccount:removingAccount.accountId];
[extSignalingController disconnect];
[[NCSettingsController sharedInstance] cleanUserAndServerStoredValues]; [[NCSettingsController sharedInstance] cleanUserAndServerStoredValues];
[[NCAPIController sharedInstance] removeProfileImageForAccount:removingAccount]; [[NCAPIController sharedInstance] removeProfileImageForAccount:removingAccount];
[[NCDatabaseManager sharedInstance] removeAccount:removingAccount.accountId]; [[NCDatabaseManager sharedInstance] removeAccount:removingAccount.accountId];
@ -326,9 +329,11 @@ NSString * const NCUserProfileImageUpdatedNotification = @"NCUserProfileImageUpd
- (void)getSignalingConfigurationWithCompletionBlock:(GetSignalingConfigCompletionBlock)block - (void)getSignalingConfigurationWithCompletionBlock:(GetSignalingConfigCompletionBlock)block
{ {
[[NCAPIController sharedInstance] getSignalingSettingsForAccount:[[NCDatabaseManager sharedInstance] activeAccount] withCompletionBlock:^(NSDictionary *settings, NSError *error) { TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
if (!error) { [[NCAPIController sharedInstance] getSignalingSettingsForAccount:activeAccount withCompletionBlock:^(NSDictionary *settings, NSError *error) {
_ncSignalingConfiguration = [[settings objectForKey:@"ocs"] objectForKey:@"data"]; if (!error && !activeAccount.invalidated) {
NSDictionary *signalingConfiguration = [[settings objectForKey:@"ocs"] objectForKey:@"data"];
[_signalingConfigutations setObject:signalingConfiguration forKey:activeAccount.accountId];
if (block) block(nil); if (block) block(nil);
} else { } else {
NSLog(@"Error while getting signaling configuration"); NSLog(@"Error while getting signaling configuration");
@ -338,19 +343,32 @@ NSString * const NCUserProfileImageUpdatedNotification = @"NCUserProfileImageUpd
} }
// SetSignalingConfiguration should be called just once // SetSignalingConfiguration should be called just once
- (void)setSignalingConfiguration - (void)setSignalingConfigurationForAccount:(NSString *)accountId
{ {
NSDictionary *signalingConfiguration = [_signalingConfigutations objectForKey:accountId];
NSString *externalSignalingServer = nil; NSString *externalSignalingServer = nil;
id server = [_ncSignalingConfiguration objectForKey:@"server"]; id server = [signalingConfiguration objectForKey:@"server"];
if ([server isKindOfClass:[NSString class]]) { if ([server isKindOfClass:[NSString class]]) {
externalSignalingServer = server; externalSignalingServer = server;
} }
NSString *externalSignalingTicket = [_ncSignalingConfiguration objectForKey:@"ticket"]; NSString *externalSignalingTicket = [signalingConfiguration objectForKey:@"ticket"];
if (externalSignalingServer && externalSignalingTicket) { if (externalSignalingServer && externalSignalingTicket) {
[[NCExternalSignalingController sharedInstance] setServer:externalSignalingServer andTicket:externalSignalingTicket]; dispatch_async(dispatch_get_main_queue(), ^{
NCExternalSignalingController *extSignalingController = [_externalSignalingControllers objectForKey:accountId];
if (!extSignalingController) {
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:accountId];
extSignalingController = [[NCExternalSignalingController alloc] initWithAccount:account server:externalSignalingServer andTicket:externalSignalingTicket];
[_externalSignalingControllers setObject:extSignalingController forKey:accountId];
}
});
} }
} }
- (NCExternalSignalingController *)externalSignalingControllerForAccount:(NSString *)accountId
{
return [_externalSignalingControllers objectForKey:accountId];
}
#pragma mark - Server Capabilities #pragma mark - Server Capabilities
- (void)getCapabilitiesWithCompletionBlock:(GetCapabilitiesCompletionBlock)block; - (void)getCapabilitiesWithCompletionBlock:(GetCapabilitiesCompletionBlock)block;