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:
Honghai Zhang
2016-05-23 11:53:14 -07:00
parent 3ebb3efd13
commit da2ba4dcba
9 changed files with 153 additions and 1 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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