HTML5 WebSocket的使用及例子
阿新 • • 發佈:2018-12-17
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 協議中,為我們實現即使服務帶來了兩大好處:
- Header 互相溝通的Header是很小的-大概只有 2 Bytes
- 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。