1

私は、RestKit 0.20 を使用して、JBoss AS 7.1.1 で実行され、REST ベースの Web サービス フレームワークとして restEASY を使用するサービスに対して REST ベースの呼び出しを行う iOS アプリケーションに取り組んでいます。

クライアント アプリが呼び出す REST サービスは、一意の識別子に基づいてオブジェクトを取得するために使用されます。これらのオブジェクトは小さい場合も大きい場合もあり (サイズが 1MB を超える)、数が多い (一度に 20? 50? 100 以上) ため、一度にすべてを取得するために 1 つの大きな呼び出しを行いたくありません。むしろ、RestKit のキュー操作サポートを使用して、オブジェクト識別子に基づいて各オブジェクトの GET 要求を作成し、呼び出しを非同期で実行することを計画していました。GET が完了すると、不要なブロックを回避するために、Objective-C ブロックを使用して各オブジェクトが処理されます。

私のRestKitクライアントコードは次のようになります...

    NSArray *identifiers = ...
    RKObjectManager *objectManager = [RKObjectManager sharedManager];

    RKResponseDescriptor *getObjResp = [RKResponseDescriptor responseDescriptorWithMapping:[MyObject mapping] pathPattern:[WebServiceHelper pathForServiceOperation:@"/objects/:uniqueIdentifier"] keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    for (int i=0; i < identifiers.count; i++) {
        NSString *identifier = [identifiers objectAtIndex:i];
        NSURL *serviceURL = [WebServiceHelper urlForServiceOperation:[NSString stringWithFormat:@"/objects/%@", identifier]];
        NSURLRequest *request = [NSURLRequest requestWithURL:serviceURL];
        RKObjectRequestOperation *requestOp = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[getObjResp]];

        [requestOp setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
            MyObject *obj = [mappingResult firstObject];
            if (self.delegate != nil) {
                [self.delegate didLoadObjectWithIdentifier:identifier myObj:obj];
            }
        } failure:^(RKObjectRequestOperation *operation, NSError *error){
            if (self.delegate != nil) {
                [self.delegate didFinishWithError:error];
            }
        }];

        [objectManager enqueueObjectRequestOperation:requestOp];
    }

そこから、オブジェクトが取得されたときに呼び出されるデリゲート メソッドは次のようになります。

-(void)didLoadObjectWithIdentifier:(NSString *)identifier myObj:(MyObject *)myObj {
    if(secureMessage != nil) {
        NSLog(@"Message %@ retrieved successfully : %@:%@", identifier, myObj);
    } else {
        NSLog(@"NO OBJ");
    }
}

検索オブジェクトに関する情報を出力できるため、呼び出しは期待どおりに機能しているようです。ただし、サービス側で奇妙な/予期しない動作が見られます。

まず、restEASY によって多数の例外がスローされていることがわかります。

13:22:02,903 WARN  [org.jboss.resteasy.core.SynchronousDispatcher] (http--0.0.0.0-8080-10) Failed executing GET /objects/BBFE39EA126F610C: org.jboss.resteasy.spi.WriterException: ClientAbortException:  java.net.SocketException: Broken pipe
    at org.jboss.resteasy.core.ServerResponse.writeTo(ServerResponse.java:262) [resteasy-jaxrs-2.3.2.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.writeJaxrsResponse(SynchronousDispatcher.java:585) [resteasy-jaxrs-2.3.2.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:506) [resteasy-jaxrs-2.3.2.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:119) [resteasy-jaxrs-2.3.2.Final.jar:]
    at org.jboss.seam.resteasy.ResteasyResourceAdapter$1.process(ResteasyResourceAdapter.java:145) [jboss-seam-resteasy.jar:2.3.0.Final]
    at org.jboss.seam.servlet.ContextualHttpServletRequest.run(ContextualHttpServletRequest.java:65) [jboss-seam.jar:2.3.0.Final]
    at org.jboss.seam.resteasy.ResteasyResourceAdapter.getResource(ResteasyResourceAdapter.java:120) [jboss-seam-resteasy.jar:2.3.0.Final]
    ...

RestKit がなんらかの方法でソケットを閉じているように見えます (または、他のエラーが原因でサーバーからのオブジェクトの読み取りが妨げられています)。ここで何が起こっているのかを説明できるドキュメントは見つかりません。

次に、リクエストがこのエラーで失敗したときに、まったく同じオブジェクトに対する別の呼び出しも見られます。GET が複数回呼び出されるのはなぜですか? RestKit は失敗した GET 要求をやり直していますか?

本当に失敗する呼び出しを診断するのが難しくなるため、restEASY 内で例外が発生する理由について主に懸念しています。誰もこの動作を見たことがありますか? これらの問題を修正する方法に関するヒントはありますか? あなたが与えることができる助けをありがとう!!

4

1 に答える 1

1

これらの例外は、切断されたクライアントが原因で発生します。つまり、プロセスが完了するのを待っている間に一部のユーザーがアプリを終了するか、(クライアント側で) ネットワーク障害が発生する可能性があります。したがって、壊れたパイプ。

于 2013-01-10T11:18:35.603 に答える