【问题标题】:RestKit/RestEASY -- ClientAbortException when enqueuing request operationsRestKit/RestEASY -- 排队请求操作时出现 ClientAbortException
【发布时间】:2012-12-19 05:33:43
【问题描述】:

我正在开发一个 iOS 应用程序,它将使用 RestKit 0.20 对在 JBoss AS 7.1.1 上运行的服务进行基于 REST 的调用,并使用 restEASY 作为其基于 REST 的 Web 服务框架。

客户端应用程序将调用的 REST 服务用于根据对象的唯一标识符检索对象。由于这些对象可能很小或很大(> 1MB 大小)并且数量很大(一次 20?50?100 或更多),我不想一次大调用来检索它们。相反,我计划使用 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 正在以某种方式关闭套接字(或者其他一些错误正在阻止从服务器读取对象)。我在文档中找不到任何可以解释这里发生的事情的内容。

不过,其次,当请求因此错误而失败时,我还看到 another 调用相同的对象。为什么 GET 被多次调用? RestKit 是否正在重做失败的 GET 请求?

我最关心的是为什么在 restEASY 中会发生异常,因为它会使诊断真正失败的调用变得困难。有没有人见过这种行为?关于如何纠正这些问题的任何提示?感谢您提供的任何帮助!

【问题讨论】:

    标签: ios rest jboss restkit resteasy


    【解决方案1】:

    这些异常是由断开连接的客户端导致的,即一些用户可能会在等待进程完成时退出应用程序或出现网络故障(在客户端)。 因此,断管。

    【讨论】:

    • 因为这是中止客户端的结果,服务(服务器)端似乎没有任何问题。或者您在客户端/服务器端是否有任何超时(这也可能是一种情况)
    • 不完全确定。我只看到服务器端的错误。在客户端,没有关于错误或连接问题的日志语句。而且,正如我所说,最终所有的对象都被返回。看起来 RestKit 正在重试所有失败的尝试并最终获得预期的一切。但是,我一直无法找到的是调用重试逻辑的位置以及为什么会首先出现错误。
    • 我应该补充一点,我知道没有客户端明确断开连接,因为我是唯一一个测试这个的人。我在开发过程中看到了这一点,而不是作为生产部署的一部分。 (由于您上面提到的原因,在现实世界中看到这样的事情我不会感到惊讶)
    • 客户端没有错误,因为没有客户端知道的失败操作,服务器正在中止连接(出于某种原因)。当您收到每个请求的响应时,客户端可能正在超时重试(RestKit 有这个功能??)
    • 我还建议监控客户端和服务器之间的 HTTP 流量,这 link 可能会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    相关资源
    最近更新 更多