mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-04-24 00:00:04 +08:00
Added truly asynchronous support to GCDWebServerStreamedResponse
This commit is contained in:
@@ -34,6 +34,19 @@
|
|||||||
*/
|
*/
|
||||||
typedef NSData* (^GCDWebServerStreamBlock)(NSError** error);
|
typedef NSData* (^GCDWebServerStreamBlock)(NSError** error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The GCDWebServerAsyncStreamBlock works like the GCDWebServerStreamBlock
|
||||||
|
* except the streamed data can be returned at a later time allowing for
|
||||||
|
* truly asynchronous generation of the data.
|
||||||
|
*
|
||||||
|
* The block must return empty NSData when done or nil on error and set the
|
||||||
|
* "error" argument which is guaranteed to be non-NULL.
|
||||||
|
*
|
||||||
|
* The block must eventually call "completionBlock" passing the streamed data
|
||||||
|
* if any and the error if applicable.
|
||||||
|
*/
|
||||||
|
typedef void (^GCDWebServerAsyncStreamBlock)(GCDWebServerBodyReaderCompletionBlock completionBlock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GCDWebServerStreamedResponse subclass of GCDWebServerResponse streams
|
* The GCDWebServerStreamedResponse subclass of GCDWebServerResponse streams
|
||||||
* the body of the HTTP response using a GCD block.
|
* the body of the HTTP response using a GCD block.
|
||||||
@@ -46,8 +59,18 @@ typedef NSData* (^GCDWebServerStreamBlock)(NSError** error);
|
|||||||
+ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block;
|
+ (instancetype)responseWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is the designated initializer for the class.
|
* Creates a response with async streamed data and a given content type.
|
||||||
|
*/
|
||||||
|
+ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a response with streamed data and a given content type.
|
||||||
*/
|
*/
|
||||||
- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block;
|
- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is the designated initializer for the class.
|
||||||
|
*/
|
||||||
|
- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
@interface GCDWebServerStreamedResponse () {
|
@interface GCDWebServerStreamedResponse () {
|
||||||
@private
|
@private
|
||||||
GCDWebServerStreamBlock _block;
|
GCDWebServerAsyncStreamBlock _block;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -39,7 +39,21 @@
|
|||||||
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type streamBlock:block]);
|
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type streamBlock:block]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (instancetype)responseWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block {
|
||||||
|
return ARC_AUTORELEASE([[[self class] alloc] initWithContentType:type asyncStreamBlock:block]);
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
|
- (instancetype)initWithContentType:(NSString*)type streamBlock:(GCDWebServerStreamBlock)block {
|
||||||
|
return [self initWithContentType:type asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
|
||||||
|
|
||||||
|
NSError* error = nil;
|
||||||
|
NSData* data = block(&error);
|
||||||
|
completionBlock(data, error);
|
||||||
|
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block {
|
||||||
if ((self = [super init])) {
|
if ((self = [super init])) {
|
||||||
_block = [block copy];
|
_block = [block copy];
|
||||||
|
|
||||||
@@ -54,8 +68,8 @@
|
|||||||
ARC_DEALLOC(super);
|
ARC_DEALLOC(super);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSData*)readData:(NSError**)error {
|
- (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block {
|
||||||
return _block(error);
|
_block(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)description {
|
- (NSString*)description {
|
||||||
|
|||||||
+19
-1
@@ -311,7 +311,7 @@ int main(int argc, const char* argv[]) {
|
|||||||
fprintf(stdout, "Running in Streaming Response mode");
|
fprintf(stdout, "Running in Streaming Response mode");
|
||||||
webServer = [[GCDWebServer alloc] init];
|
webServer = [[GCDWebServer alloc] init];
|
||||||
[webServer addHandlerForMethod:@"GET"
|
[webServer addHandlerForMethod:@"GET"
|
||||||
path:@"/"
|
path:@"/sync"
|
||||||
requestClass:[GCDWebServerRequest class]
|
requestClass:[GCDWebServerRequest class]
|
||||||
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||||
|
|
||||||
@@ -327,6 +327,24 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
}];
|
||||||
|
[webServer addHandlerForMethod:@"GET"
|
||||||
|
path:@"/async"
|
||||||
|
requestClass:[GCDWebServerRequest class]
|
||||||
|
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||||
|
|
||||||
|
__block int countDown = 10;
|
||||||
|
return [GCDWebServerStreamedResponse responseWithContentType:@"text/plain" asyncStreamBlock:^(GCDWebServerBodyReaderCompletionBlock completionBlock) {
|
||||||
|
|
||||||
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||||
|
|
||||||
|
NSData* data = countDown ? [[NSString stringWithFormat:@"%i\n", countDown--] dataUsingEncoding:NSUTF8StringEncoding] : [NSData data];
|
||||||
|
completionBlock(data, nil);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}];
|
||||||
|
|
||||||
}];
|
}];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user