1/* 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#import "ARDAppEngineClient.h" 12 13#import "RTCLogging.h" 14 15#import "ARDJoinResponse.h" 16#import "ARDMessageResponse.h" 17#import "ARDSignalingMessage.h" 18#import "ARDUtilities.h" 19 20// TODO(tkchin): move these to a configuration object. 21static NSString * const kARDRoomServerHostUrl = 22 @"https://apprtc.appspot.com"; 23static NSString * const kARDRoomServerJoinFormat = 24 @"https://apprtc.appspot.com/join/%@"; 25static NSString * const kARDRoomServerJoinFormatLoopback = 26 @"https://apprtc.appspot.com/join/%@?debug=loopback"; 27static NSString * const kARDRoomServerMessageFormat = 28 @"https://apprtc.appspot.com/message/%@/%@"; 29static NSString * const kARDRoomServerLeaveFormat = 30 @"https://apprtc.appspot.com/leave/%@/%@"; 31 32static NSString * const kARDAppEngineClientErrorDomain = @"ARDAppEngineClient"; 33static NSInteger const kARDAppEngineClientErrorBadResponse = -1; 34 35@implementation ARDAppEngineClient 36 37#pragma mark - ARDRoomServerClient 38 39- (void)joinRoomWithRoomId:(NSString *)roomId 40 isLoopback:(BOOL)isLoopback 41 completionHandler:(void (^)(ARDJoinResponse *response, 42 NSError *error))completionHandler { 43 NSParameterAssert(roomId.length); 44 45 NSString *urlString = nil; 46 if (isLoopback) { 47 urlString = 48 [NSString stringWithFormat:kARDRoomServerJoinFormatLoopback, roomId]; 49 } else { 50 urlString = 51 [NSString stringWithFormat:kARDRoomServerJoinFormat, roomId]; 52 } 53 54 NSURL *roomURL = [NSURL URLWithString:urlString]; 55 RTCLog(@"Joining room:%@ on room server.", roomId); 56 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:roomURL]; 57 request.HTTPMethod = @"POST"; 58 __weak ARDAppEngineClient *weakSelf = self; 59 [NSURLConnection sendAsyncRequest:request 60 completionHandler:^(NSURLResponse *response, 61 NSData *data, 62 NSError *error) { 63 ARDAppEngineClient *strongSelf = weakSelf; 64 if (error) { 65 if (completionHandler) { 66 completionHandler(nil, error); 67 } 68 return; 69 } 70 ARDJoinResponse *joinResponse = 71 [ARDJoinResponse responseFromJSONData:data]; 72 if (!joinResponse) { 73 if (completionHandler) { 74 NSError *error = [[self class] badResponseError]; 75 completionHandler(nil, error); 76 } 77 return; 78 } 79 if (completionHandler) { 80 completionHandler(joinResponse, nil); 81 } 82 }]; 83} 84 85- (void)sendMessage:(ARDSignalingMessage *)message 86 forRoomId:(NSString *)roomId 87 clientId:(NSString *)clientId 88 completionHandler:(void (^)(ARDMessageResponse *response, 89 NSError *error))completionHandler { 90 NSParameterAssert(message); 91 NSParameterAssert(roomId.length); 92 NSParameterAssert(clientId.length); 93 94 NSData *data = [message JSONData]; 95 NSString *urlString = 96 [NSString stringWithFormat: 97 kARDRoomServerMessageFormat, roomId, clientId]; 98 NSURL *url = [NSURL URLWithString:urlString]; 99 RTCLog(@"C->RS POST: %@", message); 100 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 101 request.HTTPMethod = @"POST"; 102 request.HTTPBody = data; 103 __weak ARDAppEngineClient *weakSelf = self; 104 [NSURLConnection sendAsyncRequest:request 105 completionHandler:^(NSURLResponse *response, 106 NSData *data, 107 NSError *error) { 108 ARDAppEngineClient *strongSelf = weakSelf; 109 if (error) { 110 if (completionHandler) { 111 completionHandler(nil, error); 112 } 113 return; 114 } 115 ARDMessageResponse *messageResponse = 116 [ARDMessageResponse responseFromJSONData:data]; 117 if (!messageResponse) { 118 if (completionHandler) { 119 NSError *error = [[self class] badResponseError]; 120 completionHandler(nil, error); 121 } 122 return; 123 } 124 if (completionHandler) { 125 completionHandler(messageResponse, nil); 126 } 127 }]; 128} 129 130- (void)leaveRoomWithRoomId:(NSString *)roomId 131 clientId:(NSString *)clientId 132 completionHandler:(void (^)(NSError *error))completionHandler { 133 NSParameterAssert(roomId.length); 134 NSParameterAssert(clientId.length); 135 136 NSString *urlString = 137 [NSString stringWithFormat:kARDRoomServerLeaveFormat, roomId, clientId]; 138 NSURL *url = [NSURL URLWithString:urlString]; 139 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 140 request.HTTPMethod = @"POST"; 141 NSURLResponse *response = nil; 142 NSError *error = nil; 143 // We want a synchronous request so that we know that we've left the room on 144 // room server before we do any further work. 145 RTCLog(@"C->RS: BYE"); 146 [NSURLConnection sendSynchronousRequest:request 147 returningResponse:&response 148 error:&error]; 149 if (error) { 150 RTCLogError(@"Error leaving room %@ on room server: %@", 151 roomId, error.localizedDescription); 152 if (completionHandler) { 153 completionHandler(error); 154 } 155 return; 156 } 157 RTCLog(@"Left room:%@ on room server.", roomId); 158 if (completionHandler) { 159 completionHandler(nil); 160 } 161} 162 163#pragma mark - Private 164 165+ (NSError *)badResponseError { 166 NSError *error = 167 [[NSError alloc] initWithDomain:kARDAppEngineClientErrorDomain 168 code:kARDAppEngineClientErrorBadResponse 169 userInfo:@{ 170 NSLocalizedDescriptionKey: @"Error parsing response.", 171 }]; 172 return error; 173} 174 175@end 176