2011-06-24 65 views
12

是否可以使用Java servlet,使客戶端可以使用接收更新創建服務器發送的事件:的Java servlet和服務器發送的事件

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

所有的例子我已經在網上找到正在使用PHP,但我會假定它應該使用Java的HTTP Servlet。

+0

您正在尋找HTML5功能「Server-Sent Events」 - 對嗎? http://today.java.net/article/2010/03/31/html5-server-push-technologies-part-1 – Robert

+0

是的,事件應該使用java servlet創建 – Chris

+0

Servlets只能應答一個傳入HTTP請求。它們的設計目的不是打開連接。你可以這樣做,但我認爲如果你這樣做的話,你的服務器將在工作線程中運行得非常快。 – Robert

回答

6

這個技巧。

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

我在JDK 1.6.0_25和使用Jetty的瀏覽器上嘗試過它,但它似乎不起作用。該servlet獲取請求並在控制檯上打印「已發送數據」消息,但該網頁未顯示響應。你使用了什麼JDK版本和瀏覽器?我是新來的整個事情。 – DPD

+0

使用jdk 1.6.0_24,我用這個tomcat,它工作得很好。另請檢查您的瀏覽器是否支持'sse'。最好使用Chrome或最新版本的Firefox。 – frewper

+0

我收到一個錯誤「EventSource的響應有一個不是UTF-8的charset(」iso-8859-1「),正在中止連接。我認爲這是默認編碼。添加'response.setCharacterEncoding(「UTF-8」);' – Bakudan

3

服務器發送的事件是一個HTML5功能。我們說「HTML5」,因此它只是客戶端功能。 這麼長的服務器可以設置https respnse頭文件「text/event-stream; charset = UTF-8」,「連接」,「保持活動」,然後它被服務器支持。您可以使用Java Servlet設置這樣的頭文件。 Here you can find a step for step guide on SSE with servlet

0

我已經創建了一個可以簡單的Java Servlet的異步模式內集成了一個非常簡單的庫,所以沒有額外的服務器線程需要爲每個客戶端:https://github.com/mariomac/jeasse

它集成了SseDispatcher(用於點對點點SSE)和SseBroadcaster(用於事件廣播)。使用示例:

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

看起來很有趣。但你爲什麼要爲它授權LGPL(而不是Apache 2)呢? –

+0

@TomFennelly我基本上選擇了「隨機」一個可以自由使用的許可證,而不受派生代碼的限制。你推薦我使用另一個? LGPL有沒有缺點? – Mario

+0

就商業友好而言,Apache 2在限制使用產品的人等方面的病毒性較低。 –