2011-11-23 103 views
6

我正在使用Restlet来实现Web服务。客户端(也使用的Restlet)向服务器连续几次电话,但经过少数调用顺利完成,进一步呼吁挂服务器,显示消息:Restlet客户端对Restlet服务器的重复调用挂起

信息:停止接受新的连接和事务。考虑增加线程的最大数量。

我想:

getContext().getParameters().add("maxThreads", "200"); 

但这并不能帮助。无论如何,似乎客户端应该能够进行无限数量的调用,并且增加maxThreads只是增加了限制。看起来我并没有在每次客户调用后释放某些资源或断开连接,但我不知道如何去做。

以下(小我可以做到)独立程序演示的问题。它从一个简单的服务器,然后客户端调用它一堆时间:

/** You may copy, modify, and re-use this code as you see fit - Jim Irrer */ 
import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import org.restlet.Application; 
import org.restlet.Component; 
import org.restlet.Request; 
import org.restlet.Response; 
import org.restlet.Restlet; 
import org.restlet.Server; 
import org.restlet.data.MediaType; 
import org.restlet.data.Method; 
import org.restlet.data.Protocol; 
import org.restlet.data.Status; 
import org.restlet.representation.InputRepresentation; 
import org.restlet.representation.Representation; 
import org.restlet.resource.ClientResource; 
import org.restlet.resource.Directory; 

public class SimpleServerPut extends Component implements Runnable { 
    private static final int PORT = 8080; 

    private static int readToByteArray(InputStream inputStream, byte[] buf) throws IOException { 
     int length = 0; 
     int b; 
     while ((b = inputStream.read()) != -1) { 
      buf[length++] = (byte)b; 
     } 
     return length; 
    } 

    @Override 
    public void run() { 
     getContext().getParameters().add("maxThreads", "200"); 

     // Create the HTTP server and listen on port PORT 
     SimpleServerPut simpleServer = new SimpleServerPut(); 
     Server server = new Server(Protocol.HTTP, PORT, simpleServer); 
     simpleServer.getClients().add(Protocol.FILE); 

     // Create an application 
     Application application = new Application(simpleServer.getContext()) { 
      @Override 
      public Restlet createRoot() { 
       return new Directory(getContext(), "C:"); 
      } 
     }; 

     // Attach the application to the component and start it 
     simpleServer.getDefaultHost().attach("/stuff/", application); 
     try { 
      server.start(); 
     } 
     catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    @Override 
    public void handle(Request request, Response response) { 
     // assume the worst 
     response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED); 
     response.setEntity("No no - Bad client! Only do PUTs.", MediaType.TEXT_PLAIN); 

     try { 
      if (request.getMethod() == Method.PUT) { 
       InputStream inputStream = request.getEntity().getStream(); 
       byte[] buf = new byte[64*1024]; 
       int totalLength = readToByteArray(inputStream, buf); 
       response.setStatus(Status.SUCCESS_OK); 
       String msg = "Number of bytes received: " + totalLength; 
       response.setEntity(msg, MediaType.TEXT_PLAIN); 
       System.out.println("server: " + msg); 
       return; 
      } 
     } 
     catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private static String callServer() throws IOException { 
     String urlText = "http://localhost:" + PORT + "/"; 
     ClientResource clientResource = new ClientResource(urlText); 
     clientResource.setReferrerRef(urlText); 

     byte[] buf = new byte[1000]; 
     for (int i = 0; i < buf.length; i++) { 
      buf[i] = (byte)((int)'a' + (i%26)); 
     } 
     ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buf); 
     Representation representation = new InputRepresentation(byteArrayInputStream, MediaType.APPLICATION_OCTET_STREAM); 
     Representation representation2 = clientResource.put(representation); 
     byte[] responseBuf = new byte[16*1024]; 
     int length = readToByteArray(representation2.getStream(), responseBuf); 
     Response response = clientResource.getResponse(); 
     Status status = response.getStatus(); 
     return "status: " + status + " message: " + new String(responseBuf, 0, length); 
    } 

    // Start server and call it a bunch of times 
    public static void main(String[] args) throws Exception { 
     SimpleServerPut simpleServer = new SimpleServerPut(); 
     new Thread(simpleServer).start(); 
     Thread.sleep(200); // cheap trick to make sure that server is running 
     // make a bunch of client calls 
     for (int t = 0; t < 100; t++) { 
      System.out.println("client count: " + (t+1) + " " + callServer()); 
     } 
     System.exit(0); 
    } 
} 
+1

maxThreads键值对param eter需要在org.restlet.Server中设置,而不是在org.restlet.Component中。像这样:'Server server = mycomponent.getServers()。add(Protocol.HTTP,“localhost”,9090); ()“ server.getContext()。getParameters()。add(”maxThreads“,”20“);' –

回答

4

添加一个系列,使客户端释放资源:

Response response = clientResource.getResponse(); 
    Status status = response.getStatus(); 
    clientResource.release(); // add this line 

到客户端,一切正常。如果客户端死了,最终服务器会超时,但这需要一段时间。

0

除了调用ClientResource.release()之外,您可能还想调用表示上的exhaust()。

Representation responseRepresentation = response.getEntity(); 
if (responseRepresentation != null) { 
    try { 
     responseRepresentation.exhaust(); 
    } catch (IOException e) { 
     // handle exception 
    } 
    responseRepresentation.release(); 
} 

this thread的相关讨论。

1

我已经解决了我的问题下载我一直在使用Restlet API

显然将.jar的最后一个稳定版本是旧版本,其中release()命令没有任何效果。

更新前的客户端日志只输出客户端开始:

Sep 05, 2012 9:50:19 AM org.restlet.engine.http.connector.HttpClientHelper start 
INFO: Starting the default HTTP client 

现在它被outputing停止过:

Sep 05, 2012 9:50:19 AM org.restlet.engine.http.connector.HttpClientHelper stop 
INFO: Stopping the default HTTP client 
+0

你介意清楚你正在使用哪个版本以及哪个版本解决了问题?它会帮助其他人(包括我!)调试问题。 –

5

我们只能通过停止对解决问题直接使用ClientResource的关联客户端(使用Restlet 2.0.15版):

Client c = (Client)clientResource.getNext(); 
try { 
    c.stop(); 
} catch (Exception e) { 
    //handle exception 
} 
+0

看来我也必须这样做才能让线程尽快死掉,但也许这是Restlet特定版本的问题? (请参阅上面的@ kassius-vargas-prestes的答案) - 您使用的是哪个版本? –

+1

我们使用的版本是2.0。15,目前最新的稳定版本(现在仍然是) – mahnkong

+0

谢谢,我们使用的是相同的版本,所以我现在将在代码库中留下这个明确的.stop()。 –

相关问题