2011-03-04 56 views
5

這是我部署到碼頭的servlet代碼:碼頭servlet沒有檢測到客戶端已斷開

public class StreamServlet extends HttpServlet 
{ 
    public void doGet(HttpServletRequest request, 
    HttpServletResponse response) throws ServletException, IOException 
    { 
    response.setContentType("text/xml; charset=UTF-8"); 
    response.setCharacterEncoding("UTF-8"); 

    InputStream is = this.getServletContext().getResourceAsStream("A.xml"); 
    BufferedReader reader = new BufferedReader( 
     new InputStreamReader(is, Charset.forName("UTF-8"))); 

    String line = ""; 
    try 
    { 
     while((line = reader.readLine()) != null) { 
     getServletContext().log(line); 
     writer.println(line); 
     writer.flush(); 
     Thread.sleep(1500); // for testing 
     } 
    } 
    catch (InterruptedException e) 
    { 
     getServletContext().log("exception",e); 
    } 
    } 
} 

然後我在命令行

curl -i http://localhost:8080/foo/servlet 

文件A.xml包含上運行約13,000行;所以curl 1.5秒後正確顯示它收到的每一行。然後我中斷了curl,但令我驚訝的是servlet繼續運行;即在這個while循環中。

while((line = reader.readLine()) != null) { 
    getServletContext().log(line); 
    writer.println(line); 
    writer.flush(); 
    Thread.sleep(1500); // for testing 
} 

它爲什麼表現出這種行爲?我沒有使用延續。我正在運行Jetty 6.1.26。我想要的是:當servlet線程檢測到客戶端已經終止http連接時,它應該停止。

回答

0

我沒有看到你在哪裏得到作家,所以我假設它來自response.getWriter()。

我認爲可能發生的事情是Jetty在將內部響應發送到客戶端之前在內部緩衝響應。它需要這樣做,因爲它需要計算響應的大小,以便它可以在HTTP響應頭中設置「Content-Length」字段。這是客戶需要的,所以它知道要閱讀多少內容。 (嗯,這不是真的需要,但這是另一個討論。)

我想Jetty實際上並沒有發送數據,直到您關閉作家。我也認爲flush()不會做任何事情,因爲它不能發送任何數據,直到它知道沒有更多的事情發生。並且它不會檢查在寫入此緩衝流時連接是否仍處於活動狀態。

嘗試此您的循環:

for(String line = reader.readLine(); line != null && !writer.checkError(); line = reader.readLine()) { 
    getServletContext().log(line); 
    writer.println(line); 
    writer.flush(); 
    Thread.sleep(1500); // for testing 
} 

我想也許writer.checkError()傳播到實際的套接字的OutputStream並檢查它是否仍然是開放的。編輯1:嗯,沒關係,我錯過了你說flush()發送數據捲曲的位。儘管如此,請嘗試循環中的checkError(),並讓我知道它是否有效。

0

不應該你期待IOException,不僅InterruptedException? 當客戶端斷開連接並且服務器嘗試寫入時,您將得到一個IOException。不是嗎? (雖然InterruptedException處理Thread.sleep部分)。