mirror of
https://github.com/swisspol/GCDWebServer.git
synced 2026-02-11 00:00:07 +08:00
Added truly asynchronous support to GCDWebServerStreamedResponse
This commit is contained in:
@@ -34,6 +34,19 @@
|
||||
*/
|
||||
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 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This method is the designated initializer for the class.
|
||||
*/
|
||||
- (instancetype)initWithContentType:(NSString*)type asyncStreamBlock:(GCDWebServerAsyncStreamBlock)block;
|
||||
|
||||
@end
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
@interface GCDWebServerStreamedResponse () {
|
||||
@private
|
||||
GCDWebServerStreamBlock _block;
|
||||
GCDWebServerAsyncStreamBlock _block;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -39,7 +39,21 @@
|
||||
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 {
|
||||
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])) {
|
||||
_block = [block copy];
|
||||
|
||||
@@ -54,8 +68,8 @@
|
||||
ARC_DEALLOC(super);
|
||||
}
|
||||
|
||||
- (NSData*)readData:(NSError**)error {
|
||||
return _block(error);
|
||||
- (void)asyncReadDataWithCompletion:(GCDWebServerBodyReaderCompletionBlock)block {
|
||||
_block(block);
|
||||
}
|
||||
|
||||
- (NSString*)description {
|
||||
|
||||
20
Mac/main.m
20
Mac/main.m
@@ -311,7 +311,7 @@ int main(int argc, const char* argv[]) {
|
||||
fprintf(stdout, "Running in Streaming Response mode");
|
||||
webServer = [[GCDWebServer alloc] init];
|
||||
[webServer addHandlerForMethod:@"GET"
|
||||
path:@"/"
|
||||
path:@"/sync"
|
||||
requestClass:[GCDWebServerRequest class]
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user