2012-10-17 19 views
5

Sto avendo un client che esegue richieste a un server che potrebbe richiedere del tempo per rispondere.Timeout socket server restlet

Quando il server ha voluto rispondere che stava gettando la seguente eccezione:

La connessione è stata interrotta. Probabilmente è stato chiuso dal cliente.

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

Quando ciò accade, il client si blocca indefinitamente.

Ecco un esempio di codice che riproduce il problema:

lato server:

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"; 
    } 
} 

lato client:

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()); 

} 

Che cosa sta succedendo qui e come faccio a eliminare l'errore ?

risposta

0

Quello che succede è che il server chiude il socket inattivo dopo 30 secondi per impostazione predefinita e non tenta di riaprire uno nuovo.

La soluzione che ho trovato è quella di impostare il parametro ioMaxIdleTimeMs su 0 che significa nessun timeout.

Ecco il codice del server di lavoro:

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(); 
} 

Nota che ho impostato sia maxIoIdleTimeMs e ioMaxIdleTimeMs. Nel mio caso si tratta di ioMaxIdleTimeMs che viene utilizzato. È il parametro usato da Jetty.

Ma se non si utilizza Jetty, ho il sospetto che potrebbe utilizzare i maxIoIdleTimeMs parametro definito in org.restlet.engine.connector.BaseHelper.java