2011-03-04 55 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部分)。