2011-06-24 37 views
12

Có thể tạo ra một sự kiện máy chủ gửi bằng servlets java để một khách hàng có thể nhận được cập nhật sử dụng:Java servlet và máy chủ gửi các sự kiện

<script> 
    var source = new EventSource('/events'); 
    source.onmessage = function(e) { 
    document.body.innerHTML += e.data + '<br>'; 
    }; 
</script> 

Tất cả các ví dụ tôi đã tìm thấy trên trang web đang sử dụng PHP nhưng tôi giả định rằng nó sẽ hoạt động bằng cách sử dụng HTTP Servlet của Java.

+0

Bạn đang tìm kiếm tính năng HTML5 "Sự kiện được máy chủ gửi" - phải không? http://today.java.net/article/2010/03/31/html5-server-push-technologies-part-1 – Robert

+0

có .. và sự kiện sẽ được tạo bằng cách sử dụng một servlet java – Chris

+0

Servlets chỉ có thể trả lời một Yêu cầu HTTP. Chúng không được thiết kế để giữ kết nối mở. Bạn có thể làm điều đó nhưng tôi cho rằng máy chủ của bạn sẽ chạy rất nhanh trong các chuỗi công việc nếu bạn làm như vậy. – Robert

Trả lời

6

điều này thực hiện thủ thuật.

HTML

<!DOCTYPE html> 


<html> 
<body onload ="registerSSE()" > 
    <script> 

     function registerSSE() 
     { 
      alert('test 1'); 
      var source = new EventSource('http://frewper:8080/hello/sse'); 
      alert('Test2'); 
      source.onmessage=function(event) 
      { 
       document.getElementById("result").innerHTML+=event.data + "<br />"; 
      }; 

      /*source.addEventListener('server-time',function (e){ 
       alert('ea'); 
      },true);*/ 
     } 
    </script> 
    <output id ="result"></output> 

</body> 
</html> 

Servlet:

import java.io.*; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 




public class sse extends HttpServlet 
{ 
public void doPost(HttpServletRequest request, HttpServletResponse response) 
{ 
    try 
    { 
     System.out.println("SSE Demo"); 
     response.setContentType("text/event-stream"); 

     PrintWriter pw = response.getWriter(); 
     int i=0; 
     while(true) 
     { 

      i++; 
      pw.write("event: server-time\n\n"); //take note of the 2 \n 's, also on the next line. 
      pw.write("data: "+ i + "\n\n"); 
      System.out.println("Data Sent!!!"+i); 
      if(i>10) 
      break; 
     } 
     pw.close(); 

    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

public void doGet(HttpServletRequest request,HttpServletResponse response) 
{ 
    doPost(request,response); 
} 

} 
+1

Tôi đã thử nó trên JDK 1.6.0_25 và trình duyệt Chrome bằng cách sử dụng Jetty nhưng nó dường như không hoạt động. servlet nhận được yêu cầu và thông báo "Đã gửi dữ liệu" được in trên bảng điều khiển nhưng trang web không hiển thị phản hồi. Bạn đã sử dụng phiên bản và trình duyệt JDK nào? Im mới cho toàn bộ điều này. – DPD

+0

sử dụng jdk 1.6.0_24, tôi đã sử dụng tomcat cho việc này và nó hoạt động hoàn toàn tốt. Đồng thời Kiểm tra xem trình duyệt của bạn có hỗ trợ 'sse' hay không. tốt nhất là sử dụng chrome hoặc phiên bản mới nhất của firefox. – frewper

+0

Tôi gặp lỗi "Phản hồi của EventSource có bộ ký tự (" iso-8859-1 ") không phải là UTF-8. Hủy kết nối". mà tôi nghĩ là mã hóa mặc định. Thêm 'response.setCharacterEncoding (" UTF-8 ");' – Bakudan

3

Server-Sent Events là một tính năng HTML5. Chúng tôi nói "HTML5", do đó, nó chỉ là tính năng phía máy khách. Máy chủ dài có thể đặt tiêu đề https respnse "văn bản/sự kiện-luồng; charset = UTF-8", "Kết nối", "giữ nguyên", sau đó nó được máy chủ hỗ trợ. Bạn có thể đặt tiêu đề như vậy với Java Servlet. Here you can find a step for step guide on SSE with servlet

0

Tôi đã tạo ra một thư viện rất đơn giản mà có thể được tích hợp trong đồng bằng Java Servlets trong chế độ không đồng bộ, vì vậy không đề máy chủ phụ được yêu cầu cho mỗi khách hàng: https://github.com/mariomac/jeasse

Nó tích hợp SseDispatcher (ví point-to SSEs) và SseBroadcaster (để phát sóng sự kiện). Ví dụ về sử dụng:

public class TestServlet extends HttpServlet { 

SseBroadcaster broadcaster = new SseBroadcaster(); 

@Override 
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    Scanner scanner = new Scanner(req.getInputStream()); 
    StringBuilder sb = new StringBuilder(); 
    while(scanner.hasNextLine()) { 
     sb.append(scanner.nextLine()); 
    } 
    System.out.println("sb = " + sb); 
    broadcaster.broadcast("message",sb.toString()); 
} 

//http://cjihrig.com/blog/the-server-side-of-server-sent-events/ 
@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
    broadcaster.addListener(req); 
} 
} 
+0

Có vẻ thú vị. Nhưng tại sao bạn lại cấp phép cho LGPL (thay vì Apache 2)? –

+0

@TomFennelly Tôi về cơ bản đã chọn "ngẫu nhiên" một giấy phép có thể được tự do sử dụng mà không có giới hạn trên mã nguồn gốc. Bạn có đề nghị tôi sử dụng cái khác không? Có bất kỳ bất lợi nào trong LGPL không? – Mario

+0

Về mặt thân thiện với doanh nghiệp, Apache 2 ít virus hơn về mặt hạn chế là những nơi mà mọi người sử dụng nó trong các sản phẩm, v.v. –

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