5

我有一个客户端向服务器发出请求,这可能需要一些时间来响应。

当服务器想要回复时,它会抛出以下异常:

连接已断开。它可能被客户关闭。

org.eclipse.jetty.io.EofException 在 org.eclipse.jetty.io.nio.SelectChannelEndPoint.blockWritable(SelectChannelEndPoint.java:435) 在 org.eclipse.jetty.http.AbstractGenerator.blockForOutput(AbstractGenerator.java:512) 在org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:159) 在 org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:101) 在 sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder. java:221) 在 sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:282) 在 sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125) 在 sun.nio.cs.StreamEncoder.write(StreamEncoder .java:135) 在 java.io.OutputStreamWriter.write(OutputStreamWriter.java:220) 在 java.io.Writer.write(Writer.java:157) 在 org.restlet.representation.StringRepresentation.write(StringRepresentation.java: 237)在 org.restlet.representation。CharacterRepresentation.write(CharacterRepresentation.java:76) at org.restlet.engine.adapter.ServerCall.writeResponseBody(ServerCall.java:509) at org.restlet.engine.adapter.ServerCall.sendResponse(ServerCall.java:453) at org .restlet.ext.jetty.internal.JettyCall.sendResponse(JettyCall.java:312) 在 org.restlet.engine.adapter.ServerAdapter.commit(ServerAdapter.java:196) 在 org.restlet.engine.adapter.HttpServerHelper.handle (HttpServerHelper.java:153) 在 org.restlet.ext.jetty.JettyServerHelper$WrappedServer.handle(JettyServerHelper.java:170) 在 org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:452) 在 org. eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:894) 在 org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler。org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:943) 的内容(AbstractHttpConnection.java:948) org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235) 的 org.eclipse .jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) 在 org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622) 在 org.eclipse.jetty.io.nio.SelectChannelEndPoint$1。在 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538) 的 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) 运行(SelectChannelEndPoint.java:46) ) 在 java.lang.Thread.run(Thread.java:722)jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run (SelectChannelEndPoint.java:46) 在 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) 在 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)在 java.lang.Thread.run(Thread.java:722)jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run (SelectChannelEndPoint.java:46) 在 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) 在 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538)在 java.lang.Thread.run(Thread.java:722)QueuedThreadPool$3.run(QueuedThreadPool.java:538) 在 java.lang.Thread.run(Thread.java:722)QueuedThreadPool$3.run(QueuedThreadPool.java:538) 在 java.lang.Thread.run(Thread.java:722)

发生这种情况时,客户端将无限期挂起。

这是一个重现问题的代码示例:

服务器端:

    public static void main(String[] args) throws Exception  {
        Context context = new Context();
        Server server = new Server(context, Protocol.HTTP, 8182, DummyServerResource.class);
        server.start();
    }

public class DummyServerResource extends ServerResource {

    @Get
    public String retrieve() throws InterruptedException {
        Thread.sleep(1000 * 20);
        return "Dummy";
    }
}

客户端:

public static void main(String[] args) throws IOException, InterruptedException {
    Context context = new Context();
    context.getParameters().add("maxIoIdleTimeMs", "0");
    Client client = new Client(context, Protocol.HTTP);
    ClientResource cr = new ClientResource("http://localhost:8182");
    cr.setNext(client);
    Representation get = cr.get();
    System.out.println(get.getText());
    Thread.sleep(1000 * 50);
    ClientResource cr2 = new ClientResource("http://localhost:8182");
    cr2.setNext(client);
    Representation get2 = cr2.get();
    System.out.println(get2.getText());

}

这里发生了什么,如何消除错误?

4

2 回答 2

2

几周前,我在 GitHub 上打开了一个关于此的问题。感谢分享。 https://github.com/restlet/restlet-framework-java/issues/675

于 2012-10-24T15:18:54.840 回答
0

默认情况下,服务器会在 30 秒后关闭空闲套接字,并且不会尝试重新打开新套接字。

我发现的解决方法是将ioMaxIdleTimeMs参数设置为 0,这意味着没有超时。

这是工作服务器代码:

public static void main(String[] args) throws Exception  {
    Context context = new Context();
    context.getParameters().add("maxIoIdleTimeMs", "0");
    context.getParameters().add("ioMaxIdleTimeMs", "0");
    Server server = new Server(context, Protocol.HTTP, 8182, DummyServerResource.class);
    server.start();
}

请注意,我设置了 maxIoIdleTimeMs 和 ioMaxIdleTimeMs。在我的情况下,使用的是 ioMaxIdleTimeMs。这是Jetty使用的参数。

但是如果你没有使用 Jetty,我怀疑它可能会使用 org.restlet.engine.connector.BaseHelper.java 中定义的参数 maxIoIdleTimeMs

于 2016-09-12T18:47:46.043 回答