Search code examples
objective-cgcdwebserver

Client cannot receive image data from gcdwebserver


I try to create a web server on iPhone to provide urls of images in ablum. Before sending response to client, I need to do some adjustment on images (something like re-size). These actions take up to 1 or 1.5 sec per image before response to client. (especially on iPhone 4) The client side cannot receive data even though messages on xcode console already showed how many bytes has been GET on some sockets. What options can I use to solve this problem?

Another question is what happens if I increase ConnectedStateCoalescingInterval value up to 2.0 or 3.0 seconds?

Thanks.

========= 2015/08/24 13:05 Updated

Here is my addHandlerForMethod:path:requestClass:asyncProcessBlock:

    [_webServer addHandlerForMethod:@"GET" path:[NSString stringWithFormat:@"/image/%@",assetId] requestClass:[GCDWebServerRequest class] asyncProcessBlock:^(GCDWebServerRequest *request, GCDWebServerCompletionBlock completionBlock)
    {
        __strong typeof(weakself) strongself = weakself;
        [strongself requestImageDataByAssetURL:assetURL completionCb:^(NSData *photoData) {
            GCDWebServerDataResponse* response = [GCDWebServerDataResponse responseWithData:photoData contentType:@"image/png"];
            completionBlock(response);
        }];
    }];

Here is requestImageDataByAssetURL:completionCb:

- (void)requestImageDataByAssetURL:(NSURL *)assetURL completionCb:(void(^)(NSData *photoData))cbfunc {
    __block NSData *photoData;
    ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
    [library assetForURL:assetURL resultBlock:^(ALAsset *asset) {
        @autoreleasepool {
            uint64_t begin = mach_absolute_time();
            // <do some image processing here>
            uint64_t end = mach_absolute_time();
            NSLog(@"Time taken to imageResize %g s", MachTimeToSecs(end - begin));
            cbfunc(photoData);
        }
    } failureBlock:^(NSError *error) {
        NSLog(@"[%@] fail. Error=%@", NSStringFromSelector(_cmd), error.localizedDescription);
        cbfunc(nil);
    }];
}

Here is the log:

[DEBUG] [2015-08-24 04:48:09 +0000] Did open connection on socket 32
[DEBUG] Connection received 221 bytes on socket 32
[DEBUG] Connection on socket 32 preflighting request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] Connection on socket 32 processing request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] [2015-08-24 04:48:10 +0000] Did open connection on socket 34
2015-08-24 12:48:10.799 xBoard[2981:3707] Time taken to imageResize 1.52039 s
[DEBUG] Connection received 221 bytes on socket 34
[DEBUG] Connection on socket 34 preflighting request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] Connection on socket 34 processing request "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" with 221 bytes body
[DEBUG] Connection sent 171 bytes on socket 32
[DEBUG] Connection sent 123575 bytes on socket 32
[DEBUG] Did close connection on socket 32
[VERBOSE] [172.16.20.174:8080] 172.16.21.97:34450 200 "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" (221 | 123746)
2015-08-24 12:48:12.028 xBoard[2981:4f0b] Time taken to imageResize 1.06382 s
[DEBUG] Connection sent 171 bytes on socket 34
[DEBUG] Connection sent 123575 bytes on socket 34
[DEBUG] Did close connection on socket 34
[VERBOSE] [172.16.20.174:8080] 172.16.21.97:50852 200 "GET /image/9D959040-9FA8-4197-8150-8DC72339955D" (221 | 123746)

We can see it creates the first socket(32).
Then creates the second socket(34) for the same image request immediately.
It seems that GCDWebServer close the first socket immediately. But why?

P.S. By the way, the client side use Android Volley library to download image instead of using web browsers.


Solution

  • There doesn't seem to be anything wrong according to the log: 2 GET requests for the path /image/9D959040-9FA8-4197-8150-8DC72339955D are processed on sockets 32 and 34, and each return 123,575 bytes.

    Try using a desktop web browser like Chrome and its web inspector. If everything works correctly, then the problem is with your Android app.