1. 程式人生 > >HTML5 WebSocket的使用及例子

HTML5 WebSocket的使用及例子

WebSocket protocol 是HTML5一種新的協議(protocol)。它是實現了瀏覽器與伺服器全雙工通訊(full-duplex)。 現在,很多網站為了實現即時通訊(real-time),所用的技術都是輪詢(polling)。輪詢是在特定的的時間間隔(time interval)(如每1秒),由瀏覽器對伺服器發出HTTP request,然後由伺服器返回最新的資料給客服端的瀏覽器。這種傳統的HTTP request d的模式帶來很明顯的缺點 – 瀏覽器需要不斷的向伺服器發出請求(request),然而HTTP request 的header是非常長的,裡面包含的資料可能只是一個很小的值,這樣會佔用很多的頻寬。 而最比較新的技術去做輪詢的效果是Comet – 用了AJAX。但這種技術雖然可達到全雙工通訊,但依然需要發出請求(reuqest)。 在 WebSocket API,瀏覽器和伺服器只需要要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。在此WebSocket 協議中,為我們實現即使服務帶來了兩大好處:

  1. Header 互相溝通的Header是很小的-大概只有 2 Bytes
  2. Server Push 伺服器可以主動傳送資料給客戶端

下面實現一個簡單PUSH例子如下: 服務端程式碼:

  public class InitServlet extends HttpServlet {


/**
* 
*/
private static final long serialVersionUID = 1L;
private static List<MessageInbound> socketList;


public void init(ServletConfig config) throws ServletException {
InitServlet.socketList = new ArrayList<MessageInbound>();
super.init(config);
System.out.println("Server start============");
}


public static List<MessageInbound> getSocketList() {
return InitServlet.socketList;
}


}

  

  public class TestWebSocketServlet extends WebSocketServlet{


private static final Logger log = Logger.getLogger(TestWebSocketServlet.class);
/**
* 
*/
private static final long serialVersionUID = 1L;
//儲存連結的容器
private  static  List<WebSocketMessageInbound> connsList = new ArrayList<WebSocketMessageInbound>();
@Override
protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request) {
// TODO Auto-generated method stub
return new WebSocketMessageInbound();
}
public class WebSocketMessageInbound extends MessageInbound{


@Override  
   protected void onClose(int status) {  
//        InitServlet.getSocketList().remove(this);  
super.onClose(status);  
log.debug("onClose");
InitServlet.getSocketList().remove(this);
   }  

   @Override  
   protected void onOpen(WsOutbound outbound) {  
    log.debug("onOpen");
       super.onOpen(outbound);  
       InitServlet.getSocketList().add(this);
   }  
@Override
protected void onBinaryMessage(ByteBuffer message) throws IOException {
// TODO Auto-generated method stub
log.debug("onBinaryMessage");
}


@Override
protected void onTextMessage(CharBuffer message) throws IOException {
// TODO Auto-generated method stub
log.debug("onTextMessage="+message);
// this.getWsOutbound().writeTextMessage(CharBuffer.wrap("===="));
// this.getWsOutbound().writeTextMessage(message);
//傳送給所有連結的
for (MessageInbound messageInbound : InitServlet.getSocketList()) {  
           CharBuffer buffer = CharBuffer.wrap(message);  
           WsOutbound outbound = messageInbound.getWsOutbound();  
           outbound.writeTextMessage(buffer);  
           outbound.flush();  
       }  
}

}
}

web.xml配置

<servlet>
<servlet-name>initServlet</servlet-name>
<servlet-class>com.demo.websocket.InitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>websocket</servlet-name>
<servlet-class>com.demo.websocket.TestWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>websocket</servlet-name>
<url-pattern>/websocket</url-pattern>
</servlet-mapping>

前臺程式碼:

  <html> 
     <head> 
         <title>WebSoket Demo</title> 
         <script type="text/javascript"> 
             //驗證瀏覽器是否支援WebSocket協議
             if (!window.WebSocket) { 
                 alert("WebSocket not supported by this browser!"); 
             } 
              var ws;
             function display() { 
                 //var valueLabel = document.getElementById("valueLabel"); 
                 //valueLabel.innerHTML = ""; 
                 ws=new WebSocket("ws://localhost:8082/SpringMVC/websocket"); 
                 //監聽訊息
                 ws.onmessage = function(event) { 
                     //valueLabel.innerHTML+ = event.data; 
                     log(event.data);
                 }; 
                 // 開啟WebSocket 
                 ws.onclose = function(event) { 
                   //WebSocket Status:: Socket Closed
                 }; 
                 // 開啟WebSocket
                 ws.onopen = function(event) { 
                    //WebSocket Status:: Socket Open
                     //// 傳送一個初始化訊息
                     ws.send("Hello, Server!"); 
                 }; 
                 ws.onerror =function(event){
                     //WebSocket Status:: Error was reported
                 };
             } 
             var log = function(s) {  
   if (document.readyState !== "complete") {  
       log.buffer.push(s);  
   } else {  
       document.getElementById("contentId").innerHTML += (s + "\n");  
   }  
}  
             function sendMsg(){
                 var msg=document.getElementById("messageId");
                 //alert(msg.value);
                 ws.send(msg.value); 
             }
         </script> 
     </head> 
     <body onload="display();"> 
         <div id="valueLabel"></div> 
         <textarea rows="20" cols="30" id="contentId"></textarea>
         <br/>
         <input name="message" id="messageId"/>
         <button id="sendButton" onClick="javascript:sendMsg()" >Send</button>
     </body> 
</html> 

備註:必須把TOMCAT7 lib目錄下的兩個jar檔案catalina.jar、tomcat-coyote.jar新增到專案的lib。