diff --git a/ProtoRPC.podspec b/ProtoRPC.podspec new file mode 100644 index 00000000000..a7b72f0e460 --- /dev/null +++ b/ProtoRPC.podspec @@ -0,0 +1,18 @@ +Pod::Spec.new do |s| + s.name = 'ProtoRPC' + s.version = '0.0.1' + s.summary = 'RPC library for ProtocolBuffers, based on gRPC' + s.homepage = 'https://github.com/grpc/grpc/tree/master/src/objective-c/ProtoRPC' + s.license = 'New BSD' + s.authors = { 'Jorge Canizales' => 'jcanizales@google.com' } + + # s.source = { :git => 'https://github.com/grpc/grpc.git', :tag => 'release-0_5_0' } + s.source_files = 'src/objective-c/ProtoRPC/*.{h,m}' + + s.platform = :ios + s.ios.deployment_target = '6.0' + s.requires_arc = true + + s.dependency 'gRPC', '~> 0.0' + s.dependency 'RxLibrary', '~> 0.0' +end diff --git a/src/objective-c/GRPCClient/GRPCMethodName.h b/src/objective-c/GRPCClient/GRPCMethodName.h index dcad8a33479..fe153dd478b 100644 --- a/src/objective-c/GRPCClient/GRPCMethodName.h +++ b/src/objective-c/GRPCClient/GRPCMethodName.h @@ -37,7 +37,8 @@ // A fully-qualified gRPC method name. Full qualification is needed because a gRPC endpoint can // implement multiple interfaces. -// TODO(jcanizales): Is this proto-specific, or actual part of gRPC? If the former, move one layer up. +// TODO(jcanizales): Move to ProtoRPC package. +// TODO(jcanizales): Rename interface -> service. @interface GRPCMethodName : NSObject @property(nonatomic, readonly) NSString *package; @property(nonatomic, readonly) NSString *interface; diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h new file mode 100644 index 00000000000..b6375f52d6f --- /dev/null +++ b/src/objective-c/ProtoRPC/ProtoRPC.h @@ -0,0 +1,46 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import +#import + +@interface ProtoRPC : GRPCCall + +- (instancetype)initWithHost:(NSString *)host + method:(GRPCMethodName *)method + requestsWriter:(id)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable NS_DESIGNATED_INITIALIZER; + +- (void)start; +@end diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m new file mode 100644 index 00000000000..1b046845cef --- /dev/null +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -0,0 +1,81 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "ProtoRPC.h" + +#import + +@implementation ProtoRPC { + id _responseWriteable; +} + +- (instancetype)initWithHost:(NSString *)host + method:(GRPCMethodName *)method + requestsWriter:(id)requestWriter { + return [self initWithHost:host + method:method + requestsWriter:requestsWriter + responseClass:nil + responsesWriteable:nil]; +} + +// Designated initializer +- (instancetype)initWithHost:(NSString *)host + method:(GRPCMethodName *)method + requestsWriter:(id)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable { + // Because we can't tell the type system to constrain the class, we need to check at runtime: + if (![class respondsToSelector:@selector(parseFromData:)]) { + [NSException raise:NSInvalidArgumentException + format:@"A protobuf class to parse the responses must be provided."]; + } + if ((self = [super initWithHost:host method:method requestsWriter:requestsWriter])) { + _responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { + [responsesWriteable didReceiveValue:[responseClass parseFromData:value]]; + } completionHandler:^(NSError *errorOrNil) { + [responsesWriteable didFinishWithError:errorOrNil]; + }]; + } + return self; +} + +- (void)start { + [self startWithWriteable:_responseWriteable]; +} + +- (void)startWithWriteable:(id)writeable { + [super startWithWriteable:writeable]; + _responseWriteable = nil; +} +@end diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h new file mode 100644 index 00000000000..c5ef820f48a --- /dev/null +++ b/src/objective-c/ProtoRPC/ProtoService.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import + +@class ProtoRPC; +@protocol GRXWriteable; +@protocol GRXWriter; + +@interface ProtoService : NSObject +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER; + +- (ProtoRPC *)RPCToMethod:(NSString *)method + requestsWriter:(id)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable; +@end diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m new file mode 100644 index 00000000000..45d015e1316 --- /dev/null +++ b/src/objective-c/ProtoRPC/ProtoService.m @@ -0,0 +1,81 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "ProtoService.h" + +#import +#import +#import + +#import "ProtoRPC.h" + +@implementation ProtoService { + NSString *_host; + NSString *_packageName; + NSString *_serviceName; +} + +- (instancetype)init { + return [self initWithHost:nil]; +} + +// Designated initializer +- (instancetype)initWithHost:(NSString *)host + packageName:(NSString *)packageName + serviceName:(NSString *)serviceName { + if (!host || !serviceName) { + [NSException raise:NSInvalidArgumentException + format:@"Neither host nor serviceName can be nil."]; + } + if ((self = [super init])) { + _host = [host copy]; + _packageName = [packageName copy]; + _serviceName = [serviceName copy]; + } + return self; +} + +- (ProtoRPC *)RPCToMethod:(NSString *)method + requestsWriter:(id)requestsWriter + responseClass:(Class)responseClass + responsesWriteable:(id)responsesWriteable { + GRPCMethodName *methodName = [[GRPCMethodName alloc] initWithPackage:_packageName + interface:_serviceName + method:_method]; + return [[ProtoRPC alloc] initWithHost:_host + method:methodName + requestsWriter:requestsWriter + responseClass:responseClass + responsesWriteable:responsesWriteable]; +} +@end diff --git a/src/objective-c/RxLibrary/GRXWriteable.h b/src/objective-c/RxLibrary/GRXWriteable.h index cdcb99f4590..6f6ea142e01 100644 --- a/src/objective-c/RxLibrary/GRXWriteable.h +++ b/src/objective-c/RxLibrary/GRXWriteable.h @@ -50,10 +50,16 @@ typedef void (^GRXValueHandler)(id value); typedef void (^GRXCompletionHandler)(NSError *errorOrNil); +typedef void (^GRXSingleValueHandler)(id value, NSError *errorOrNil); +typedef void (^GRXStreamHandler)(BOOL done, id value, NSError *error); // Utility to create objects that conform to the GRXWriteable protocol, from // blocks that handle each of the two methods of the protocol. @interface GRXWriteable : NSObject + ++ (instancetype)writeableWithSingleValueHandler:(GRXSingleValueHandler)handler; ++ (instancetype)writeableWithStreamHandler:(GRXStreamHandler)handler; + - (instancetype)initWithValueHandler:(GRXValueHandler)valueHandler completionHandler:(GRXCompletionHandler)completionHandler NS_DESIGNATED_INITIALIZER; diff --git a/src/objective-c/RxLibrary/GRXWriteable.m b/src/objective-c/RxLibrary/GRXWriteable.m index 7231f06462a..7000a078d1e 100644 --- a/src/objective-c/RxLibrary/GRXWriteable.m +++ b/src/objective-c/RxLibrary/GRXWriteable.m @@ -38,6 +38,30 @@ GRXCompletionHandler _completionHandler; } ++ (instancetype)writeableWithSingleValueHandler:(GRXSingleValueHandler)handler { + if (!handler) { + return [[self alloc] init]; + } + return [[self alloc] initWithValueHandler:^(id value) { + handler(value, nil); + } completionHandler:^(NSError *errorOrNil) { + if (errorOrNil) { + handler(nil, errorOrNil); + } + }]; +} + ++ (instancetype)writeableWithStreamHandler:(GRXStreamHandler)handler { + if (!handler) { + return [[self alloc] init]; + } + return [[self alloc] initWithValueHandler:^(id value) { + handler(NO, value, nil); + } completionHandler:^(NSError *errorOrNil) { + handler(YES, nil, errorOrNil); + }]; +} + - (instancetype)init { return [self initWithValueHandler:nil completionHandler:nil]; } diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile index 8b1a90e39bd..7752d240d09 100644 --- a/src/objective-c/examples/Sample/Podfile +++ b/src/objective-c/examples/Sample/Podfile @@ -2,6 +2,7 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' pod 'gRPC', :path => "../../../.." +pod 'ProtoRPC', :path => "../../../.." pod 'Route_guide', :path => "RouteGuideClient" pod 'RemoteTest', :path => "RemoteTestClient" diff --git a/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec index 4790594bc5b..8770804617a 100644 --- a/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec @@ -14,4 +14,5 @@ Pod::Spec.new do |s| s.requires_arc = true s.dependency 'ProtocolBuffers', '~> 1.9' + s.dependency 'ProtoRPC', '~> 0.0' end diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h index 6db981dc5bb..92c58a1652d 100644 --- a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h +++ b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.h @@ -4,6 +4,7 @@ #import "Empty.pb.h" #import "Messages.pb.h" +#import // @@protoc_insertion_point(imports) @class ObjectiveCFileOptions; @@ -78,4 +79,88 @@ @end + +@protocol GRXWriteable; +@protocol GRXWriter; + +@protocol RMTTestService + +#pragma mark EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty) + +// One empty request followed by one empty response. +- (void)emptyCallWithRequest:(RMTEmpty *)request + handler:(void(^)(RMTEmpty *response, NSError *error))handler; + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToEmptyCallWithRequest:(RMTEmpty *)request + handler:(void(^)(RMTEmpty *response, NSError *error))handler; + + +#pragma mark UnaryCall(SimpleRequest) returns (SimpleResponse) + +// One request followed by one response. +- (void)unaryCallWithRequest:(RMTSimpleRequest *)request + handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler; + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToUnaryCallWithRequest:(RMTSimpleRequest *)request + handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler; + + +#pragma mark StreamingOutputCall(StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse) + +// One request followed by a sequence of responses (streamed download). +// The server returns the payload with client desired type and sizes. +- (void)streamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler; + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToStreamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler; + + +#pragma mark StreamingInputCall(stream StreamingInputCallRequest) returns (StreamingInputCallResponse) + +// A sequence of requests followed by one response (streamed upload). +// The server returns the aggregated size of client payload as the result. +- (void)streamingInputCallWithRequestsWriter:(id)request + handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler; + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToStreamingInputCallWithRequestsWriter:(id)request + handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler; + + +#pragma mark FullDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse) + +// A sequence of requests with each request served by the server immediately. +// As one request could lead to multiple responses, this interface +// demonstrates the idea of full duplexing. +- (void)fullDuplexCallWithRequestsWriter:(id)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler; + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToFullDuplexCallWithRequestsWriter:(id)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler; + + +#pragma mark HalfDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse) + +// A sequence of requests followed by a sequence of responses. +// The server buffers all the client requests and then serves them in order. A +// stream of responses are returned to the client when the server starts with +// first request. +- (void)halfDuplexCallWithRequestsWriter:(id)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler; + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToHalfDuplexCallWithRequestsWriter:(id)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler; + +@end + +// Basic service implementation, over gRPC, that only does marshalling and parsing. +@interface RMTTestService : ProtoService +@end + // @@protoc_insertion_point(global_scope) diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m index bd6a29df413..b05bcc7218f 100644 --- a/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m +++ b/src/objective-c/examples/Sample/RemoteTestClient/Test.pb.m @@ -1,6 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! #import "Test.pb.h" + +#import +#import // @@protoc_insertion_point(imports) @implementation RMTTestRoot @@ -24,4 +27,129 @@ static PBExtensionRegistry* extensionRegistry = nil; @end +static NSString *const kServiceName = @"grpc.testing.TestService"; + +@implementation RMTTestService + +- (instancetype)initWithHost:(NSString *)host { + return (self = [super initWithHost:host serviceName:kServiceName]); +} + + +#pragma mark EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty) + +// One empty request followed by one empty response. +- (void)emptyCallWithRequest:(RMTEmpty *)request + handler:(void(^)(RMTEmpty *response, NSError *error))handler { + [[self RPCToEmptyCallWithRequest:request handler:handler] start]; +} + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToEmptyCallWithRequest:(RMTEmpty *)request + handler:(void(^)(RMTEmpty *response, NSError *error))handler { + return [self RPCToMethod:@"EmptyCall" + requestsWriter:[GRXWriter writerWithValue:request]; + responseClass:[RMTEmpty class] + responsesWriteable:[GRXWriteable writeableWithSingleValueHandler:handler]]; +} + + +#pragma mark UnaryCall(SimpleRequest) returns (SimpleResponse) + +// One request followed by one response. +- (void)unaryCallWithRequest:(RMTSimpleRequest *)request + handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler { + [[self RPCToUnaryCallWithRequest:request handler:handler] start]; +} + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToUnaryCallWithRequest:(RMTSimpleRequest *)request + handler:(void(^)(RMTSimpleResponse *response, NSError *error))handler { + return [self RPCToMethod:@"UnaryCall" + requestsWriter:[GRXWriter writerWithValue:request]; + responseClass:[RMTSimpleResponse class] + responsesWriteable:[GRXWriteable writeableWithSingleValueHandler:handler]]; +} + + +#pragma mark StreamingOutputCall(StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse) + +// One request followed by a sequence of responses (streamed download). +// The server returns the payload with client desired type and sizes. +- (void)streamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler { + [[self RPCToStreamingOutputCallWithRequest:request handler:handler] start]; +} + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToStreamingOutputCallWithRequest:(RMTStreamingOutputCallRequest *)request + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler { + return [self RPCToMethod:@"StreamingOutputCall" + requestsWriter:[GRXWriter writerWithValue:request]; + responseClass:[RMTStreamingOutputCallResponse class] + responsesWriteable:[GRXWriteable writeableWithStreamHandler:handler]]; +} + + +#pragma mark StreamingInputCall(stream StreamingInputCallRequest) returns (StreamingInputCallResponse) + +// A sequence of requests followed by one response (streamed upload). +// The server returns the aggregated size of client payload as the result. +- (void)streamingInputCallWithRequestsWriter:(id)requestsWriter + handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler { + [[self RPCToStreamingInputCallWithRequestsWriter:requestsWriter handler:handler] start]; +} + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToStreamingInputCallWithRequestsWriter:(id)requestsWriter + handler:(void(^)(RMTStreamingInputCallResponse *response, NSError *error))handler { + return [self RPCToMethod:@"StreamingInputCall" + requestsWriter:requestsWriter; + responseClass:[RMTStreamingInputCallResponse class] + responsesWriteable:[GRXWriteable writeableWithSingleValueHandler:handler]]; +} + + +#pragma mark FullDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse) + +// A sequence of requests with each request served by the server immediately. +// As one request could lead to multiple responses, this interface +// demonstrates the idea of full duplexing. +- (void)fullDuplexCallWithRequestsWriter:(id)requestsWriter + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler { + [[self RPCToFullDuplexCallWithRequestsWriter:requestsWriter handler:handler] start]; +} + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToFullDuplexCallWithRequestsWriter:(id)requestsWriter + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler { + return [self RPCToMethod:@"FullDuplexCall" + requestsWriter:requestsWriter; + responseClass:[RMTStreamingOutputCallResponse class] + responsesWriteable:[GRXWriteable writeableWithStreamHandler:handler]]; +} + + +#pragma mark HalfDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse) + +// A sequence of requests followed by a sequence of responses. +// The server buffers all the client requests and then serves them in order. A +// stream of responses are returned to the client when the server starts with +// first request. +- (void)halfDuplexCallWithRequestsWriter:(id)requestsWriter + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler { + [[self RPCToHalfDuplexCallWithRequestsWriter:requestsWriter handler:handler] start]; +} + +// Returns a not-yet-started RPC object. +- (ProtoRPC *)RPCToHalfDuplexCallWithRequestsWriter:(id)requestsWriter + handler:(void(^)(BOOL done, RMTStreamingOutputCallResponse *response, NSError *error))handler { + return [self RPCToMethod:@"HalfDuplexCall" + requestsWriter:requestsWriter; + responseClass:[RMTStreamingOutputCallResponse class] + responsesWriteable:[GRXWriteable writeableWithStreamHandler:handler]]; +} + +@end + // @@protoc_insertion_point(global_scope)