2012-03-29 33 views
6

Tôi đã thử nghiệm HttpResponse#flushBufferPrintWriter#flush trên Tomcat 7 bên dưới, nhưng có vẻ như phản hồi thay vì bỏ qua chúng hơn là xóa nội dung trên dây asap như mong đợi.Tomcat không xóa bộ đệm phản hồi

import java.io.IOException; 
import java.io.PrintWriter; 

import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

@WebServlet("/HelloServlet") 
public class HelloServlet extends HttpServlet { 

    private static final long serialVersionUID = 1L; 

    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 

     PrintWriter pw = response.getWriter(); 
     pw.println("say hi now"); 
     pw.flush(); 
     response.flushBuffer(); 
     try { 
      Thread.sleep(5000); 
     } catch (Exception e) { 
     } 
     pw.println("say bye in 5 seconds"); 

    } 

} 

Máy rút tiền hiển thị "hi" và "tạm biệt" với nhau sau khi trì hoãn. Đó có phải là hành vi sai trái hoặc dự định không?

@EDIT

Theo đề nghị @Tomasz Nurkiewicz 's, tôi đã kiểm tra một lần nữa với curl sau đó vấn đề này đã biến mất. Dường như các trình duyệt chuẩn và gói tcp/ip monitorsmall pieces of contents từ cùng một phản hồi http để hiển thị chúng cùng nhau.

@EDIT 2

Nó cũng quan sát thấy rằng cả hai HttpResponse#flushBufferPrintWriter#flushTomcat 7 để gửi cho khách hàng chunked data.

+0

Tôi tin rằng đó là cấu hình máy chủ ứng dụng. Vui lòng xem [bài đăng của tôi] (http://stackoverflow.com/questions/43453508/end-to-end-reactive-streaming-restful-service). –

Trả lời

2

API cho flushBuffer() là rất chính xác:

Lực lượng bất kỳ nội dung trong bộ đệm được viết cho khách hàng. Cuộc gọi đến phương thức này sẽ tự động cam kết phản hồi, có nghĩa là mã trạng thái và tiêu đề sẽ được ghi.

Vì vậy, Tomcat không được triển khai theo thông số kỹ thuật (bộ đệm tích cực hơn và giữ bung ra nếu quá nhỏ) hoặc ứng dụng khách (trình duyệt) chờ thêm thông tin trước khi thực sự hiển thị nó.

Bạn có thể thử dùng hoặc nc thay thế không?

+0

tôi rình mò trên dây, đó là một vấn đề triển khai trên tomcat. – sof

+0

Sự cố đã biến mất nếu bạn thử với 'curl'. Nó phải là 'không liên quan' với tomcat. – sof

5

Tôi vừa gặp vấn đề tương tự. Để ngừng các trình duyệt chờ cho đến khi trang tải xong trước khi thực hiện bất kỳ kết xuất nào bạn cần bắt đầu bằng:

response.setContentType("text/html;charset=UTF-8"); 
2

Tôi cũng gặp vấn đề đó. Và tôi cũng phát hiện ra rằng vấn đề sẽ biến mất với curl. Với một số sniffing, nó bật ra rằng thủ phạm là mã hóa gzip. Để nén phản hồi, gzip đợi cho đến khi PrintWriter nằm bên dưới được đóng (nghĩa là, cho đến khi đáp ứng đầy đủ được viết) và sau đó tạo ra kết quả nén. Về phía khách hàng, điều này có nghĩa rằng bạn không nhận được bất cứ điều gì trở lại cho đến khi phản ứng đầy đủ đã sẵn sàng. Curl, mặt khác, không phát hành một gzip Accept-Encoding: đến máy chủ, và đó là lý do tại sao nó hoạt động, và bạn có thể nhận được đầu ra chunked bình thường như dự định.

0

Một nguyên nhân có thể không được nêu ra cho hiện tượng này là phần mềm chống vi-rút. Tôi đã quan sát hành vi tương tự trên máy của tôi: máy chủ gửi dữ liệu chunked, curl làm việc, trình duyệt bình thường không, và cũng Fiddler xác nhận rằng nó không phải là máy chủ bị chặn. Vì vậy, sau một thời gian tôi nghi ngờ việc bảo vệ web của Sophos (phần mềm chống vi-rút mà chủ lao động của tôi sử dụng) để can thiệp, và thực sự họ xác nhận tại https://community.sophos.com/kb/en-us/115656 rằng họ chặn dữ liệu chunked cho đến khi phản hồi hoàn tất, ngoại trừ một số loại mime nhất định thường được sử dụng để truyền dữ liệu đa phương tiện.

Khi người kiểm tra nhanh có thể chạy bản demo HTTP-Push tại http://www.pushlets.com.Nếu nó không hoạt động, rất có khả năng là máy khách có vấn đề chung với việc xử lý dữ liệu chunked của kiểu text/html đúng cách.

Các vấn đề liên quan