2011-11-23 101 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()。 –

相關問題