Pass around the candidate removals events in IOS clients
When local candidates are removed, signal to RTCPeerConnection and eventually send to the remote client. When a candidate-removal message is received, notify the native PeerConnection. BUG= R=tkchin@webrtc.org Review URL: https://codereview.webrtc.org/1972483002 . Cr-Commit-Position: refs/heads/master@{#12852}
This commit is contained in:
@ -330,6 +330,7 @@ static BOOL const kARDAppClientEnableTracing = NO;
|
||||
[_messageQueue insertObject:message atIndex:0];
|
||||
break;
|
||||
case kARDSignalingMessageTypeCandidate:
|
||||
case kARDSignalingMessageTypeCandidateRemoval:
|
||||
[_messageQueue addObject:message];
|
||||
break;
|
||||
case kARDSignalingMessageTypeBye:
|
||||
@ -409,6 +410,16 @@ static BOOL const kARDAppClientEnableTracing = NO;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)peerConnection:(RTCPeerConnection *)peerConnection
|
||||
didRemoveIceCandidates:(NSArray<RTCIceCandidate *> *)candidates {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
ARDICECandidateRemovalMessage *message =
|
||||
[[ARDICECandidateRemovalMessage alloc]
|
||||
initWithRemovedCandidates:candidates];
|
||||
[self sendSignalingMessage:message];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)peerConnection:(RTCPeerConnection *)peerConnection
|
||||
didOpenDataChannel:(RTCDataChannel *)dataChannel {
|
||||
}
|
||||
@ -573,6 +584,12 @@ static BOOL const kARDAppClientEnableTracing = NO;
|
||||
[_peerConnection addIceCandidate:candidateMessage.candidate];
|
||||
break;
|
||||
}
|
||||
case kARDSignalingMessageTypeCandidateRemoval: {
|
||||
ARDICECandidateRemovalMessage *candidateMessage =
|
||||
(ARDICECandidateRemovalMessage *)message;
|
||||
[_peerConnection removeIceCandidates:candidateMessage.candidates];
|
||||
break;
|
||||
}
|
||||
case kARDSignalingMessageTypeBye:
|
||||
// Other client disconnected.
|
||||
// TODO(tkchin): support waiting in room for next client. For now just
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
typedef enum {
|
||||
kARDSignalingMessageTypeCandidate,
|
||||
kARDSignalingMessageTypeCandidateRemoval,
|
||||
kARDSignalingMessageTypeOffer,
|
||||
kARDSignalingMessageTypeAnswer,
|
||||
kARDSignalingMessageTypeBye,
|
||||
@ -37,6 +38,15 @@ typedef enum {
|
||||
|
||||
@end
|
||||
|
||||
@interface ARDICECandidateRemovalMessage : ARDSignalingMessage
|
||||
|
||||
@property(nonatomic, readonly) NSArray<RTCIceCandidate *> *candidates;
|
||||
|
||||
- (instancetype)initWithRemovedCandidates:
|
||||
(NSArray<RTCIceCandidate *> *)candidates;
|
||||
|
||||
@end
|
||||
|
||||
@interface ARDSessionDescriptionMessage : ARDSignalingMessage
|
||||
|
||||
@property(nonatomic, readonly) RTCSessionDescription *sessionDescription;
|
||||
|
||||
@ -16,7 +16,8 @@
|
||||
#import "RTCIceCandidate+JSON.h"
|
||||
#import "RTCSessionDescription+JSON.h"
|
||||
|
||||
static NSString const *kARDSignalingMessageTypeKey = @"type";
|
||||
static NSString * const kARDSignalingMessageTypeKey = @"type";
|
||||
static NSString * const kARDTypeValueRemoveCandidates = @"remove-candidates";
|
||||
|
||||
@implementation ARDSignalingMessage
|
||||
|
||||
@ -47,6 +48,12 @@ static NSString const *kARDSignalingMessageTypeKey = @"type";
|
||||
RTCIceCandidate *candidate =
|
||||
[RTCIceCandidate candidateFromJSONDictionary:values];
|
||||
message = [[ARDICECandidateMessage alloc] initWithCandidate:candidate];
|
||||
} else if ([typeString isEqualToString:kARDTypeValueRemoveCandidates]) {
|
||||
RTCLogInfo(@"Received remove-candidates message");
|
||||
NSArray<RTCIceCandidate *> *candidates =
|
||||
[RTCIceCandidate candidatesFromJSONDictionary:values];
|
||||
message = [[ARDICECandidateRemovalMessage alloc]
|
||||
initWithRemovedCandidates:candidates];
|
||||
} else if ([typeString isEqualToString:@"offer"] ||
|
||||
[typeString isEqualToString:@"answer"]) {
|
||||
RTCSessionDescription *description =
|
||||
@ -84,6 +91,27 @@ static NSString const *kARDSignalingMessageTypeKey = @"type";
|
||||
|
||||
@end
|
||||
|
||||
@implementation ARDICECandidateRemovalMessage
|
||||
|
||||
@synthesize candidates = _candidates;
|
||||
|
||||
- (instancetype)initWithRemovedCandidates:(
|
||||
NSArray<RTCIceCandidate *> *)candidates {
|
||||
NSParameterAssert(candidates.count);
|
||||
if (self = [super initWithType:kARDSignalingMessageTypeCandidateRemoval]) {
|
||||
_candidates = candidates;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSData *)JSONData {
|
||||
return
|
||||
[RTCIceCandidate JSONDataForIceCandidates:_candidates
|
||||
withType:kARDTypeValueRemoveCandidates];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ARDSessionDescriptionMessage
|
||||
|
||||
@synthesize sessionDescription = _sessionDescription;
|
||||
|
||||
@ -233,6 +233,7 @@ static NSString const *kARDWSSMessagePayloadKey = @"msg";
|
||||
// Should not receive answer in loopback scenario.
|
||||
break;
|
||||
case kARDSignalingMessageTypeCandidate:
|
||||
case kARDSignalingMessageTypeCandidateRemoval:
|
||||
// Send back to server.
|
||||
[self sendMessage:message];
|
||||
break;
|
||||
|
||||
@ -13,6 +13,10 @@
|
||||
@interface RTCIceCandidate (JSON)
|
||||
|
||||
+ (RTCIceCandidate *)candidateFromJSONDictionary:(NSDictionary *)dictionary;
|
||||
+ (NSArray<RTCIceCandidate *> *)candidatesFromJSONDictionary:
|
||||
(NSDictionary *)dictionary;
|
||||
+ (NSData *)JSONDataForIceCandidates:(NSArray<RTCIceCandidate *> *)candidates
|
||||
withType:(NSString *)typeValue;
|
||||
- (NSData *)JSONData;
|
||||
|
||||
@end
|
||||
|
||||
@ -17,6 +17,8 @@ static NSString const *kRTCICECandidateTypeValue = @"candidate";
|
||||
static NSString const *kRTCICECandidateMidKey = @"id";
|
||||
static NSString const *kRTCICECandidateMLineIndexKey = @"label";
|
||||
static NSString const *kRTCICECandidateSdpKey = @"candidate";
|
||||
static NSString const *kRTCICECandidatesTypeKey = @"candidates";
|
||||
|
||||
|
||||
@implementation RTCIceCandidate (JSON)
|
||||
|
||||
@ -30,6 +32,43 @@ static NSString const *kRTCICECandidateSdpKey = @"candidate";
|
||||
sdpMid:mid];
|
||||
}
|
||||
|
||||
+ (NSData *)JSONDataForIceCandidates:(NSArray<RTCIceCandidate *> *)candidates
|
||||
withType:(NSString *)typeValue {
|
||||
NSMutableArray *jsonCandidates =
|
||||
[NSMutableArray arrayWithCapacity:candidates.count];
|
||||
for (RTCIceCandidate *candidate in candidates) {
|
||||
NSDictionary *jsonCandidate = [candidate JSONDictionary];
|
||||
[jsonCandidates addObject:jsonCandidate];
|
||||
}
|
||||
NSDictionary *json = @{
|
||||
kRTCICECandidateTypeKey : typeValue,
|
||||
kRTCICECandidatesTypeKey : jsonCandidates
|
||||
};
|
||||
NSError *error = nil;
|
||||
NSData *data =
|
||||
[NSJSONSerialization dataWithJSONObject:json
|
||||
options:NSJSONWritingPrettyPrinted
|
||||
error:&error];
|
||||
if (error) {
|
||||
RTCLogError(@"Error serializing JSON: %@", error);
|
||||
return nil;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
+ (NSArray<RTCIceCandidate *> *)candidatesFromJSONDictionary:
|
||||
(NSDictionary *)dictionary {
|
||||
NSArray *jsonCandidates = dictionary[kRTCICECandidatesTypeKey];
|
||||
NSMutableArray<RTCIceCandidate *> *candidates =
|
||||
[NSMutableArray arrayWithCapacity:jsonCandidates.count];
|
||||
for (NSDictionary *jsonCandidate in jsonCandidates) {
|
||||
RTCIceCandidate *candidate =
|
||||
[RTCIceCandidate candidateFromJSONDictionary:jsonCandidate];
|
||||
[candidates addObject:candidate];
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
- (NSData *)JSONData {
|
||||
NSDictionary *json = @{
|
||||
kRTCICECandidateTypeKey : kRTCICECandidateTypeValue,
|
||||
@ -49,4 +88,13 @@ static NSString const *kRTCICECandidateSdpKey = @"candidate";
|
||||
return data;
|
||||
}
|
||||
|
||||
- (NSDictionary *)JSONDictionary{
|
||||
NSDictionary *json = @{
|
||||
kRTCICECandidateMLineIndexKey : @(self.sdpMLineIndex),
|
||||
kRTCICECandidateMidKey : self.sdpMid,
|
||||
kRTCICECandidateSdpKey : self.sdp
|
||||
};
|
||||
return json;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user