一、概述
作為HTML5新特性之一的WebSocket組件,在實時性有一定要求的WEB應(yīng)用開發(fā)中還是有一定用武之地,高版本的IE、Chrome、FF瀏覽器都支持Websocket,標(biāo)準(zhǔn)的Websocket通信是基于RFC6455實現(xiàn)服務(wù)器端與客戶端握手與消息接發(fā)的。如果對Websocket通信不是太理解,可以查看RFC文檔即可,簡單說就是通過發(fā)送HTTP請求,實現(xiàn)雙方握手,將無狀態(tài)的HTTP通信協(xié)議進(jìn)一步升級成有狀態(tài)的通信協(xié)議,同時Websocket還支持子協(xié)議選項與安全傳輸。標(biāo)準(zhǔn)的websocket連接URL以ws開頭,如果是基于TLS的則以wss開頭。基于Websocket可以很方便的開發(fā)基于web聊天程序,各種網(wǎng)頁消息通知與推送通知。
如果非要扒一扒Websocket的今生前世的話,還記得最早的基于HTTP輪詢實現(xiàn)網(wǎng)頁即時通信的方式,那種做法比較消耗資源、于是有人改進(jìn)了編程CometD長連接方式,可是本質(zhì)上還是換湯不換藥,而websocket的出現(xiàn)正好解決了這些問題,但是很多瀏覽器的低版本還是不支持websocket,于是還催生了一些基于websocket理念實現(xiàn)的JS通信框架,其中學(xué)得比較像的有SockJS與socket.io,他們都號稱支持websocket,然后如果瀏覽器端不支持原生的websocket,它們會自動啟用fallback選項使用其它諸如ajax、Http輪詢、長輪詢/連接、甚至是flash的socket等機(jī)制實現(xiàn)模擬websocket的工作方式,但是他們最大的弊端是如果客戶端使用了這些框架,服務(wù)器必須用它們,否則等待開發(fā)者就是一大堆無法回避的問題,同時很多都是無解的。主要原因在于它們實現(xiàn)自己的協(xié)議集,不照它們的格式處理數(shù)據(jù)沒法玩。閑話說的有點多。
二、實現(xiàn)步驟
Tomcat7的高版本中實現(xiàn)了Websocket服務(wù)器端RFC6455標(biāo)準(zhǔn)協(xié)議,可以跟瀏覽器端websocket進(jìn)行通信,首先要做好如下幾步:
1.安裝高版本JDK – JDK8
2.安裝Tomcat 7.0.64
3.在eclipse中建立一個動態(tài)的web項目
根據(jù)JSR標(biāo)準(zhǔn),Java中實現(xiàn)websocket的標(biāo)準(zhǔn)接口可以基于注解方式,tomcat也搞好了,只有我們實現(xiàn)如下代碼,即可創(chuàng)建一個websocket回聲服務(wù)器:
package com.websocket.demo; import java.io.IOException; import java.nio.ByteBuffer; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint(value = "/echo") public class EchoExample { @OnMessage public void echoTextMessage(Session session, String msg, boolean last) { try { if (session.isOpen()) { System.out.println("received from client message = " + msg); session.getBasicRemote().sendText(msg, last); } } catch (IOException e) { try { session.close(); } catch (IOException e1) { } } } @OnOpen public void openConn(Session session) throws IOException { session.getBasicRemote().sendText("hello web socket"); // means open it } @OnMessage public void echoBinaryMessage(Session session, ByteBuffer bb, boolean last) { System.out.println("send binary message..."); try { if (session.isOpen()) { System.out.println("byte buffer lenghth : " + bb.array().length); System.out.println("byte buffer content: " + ((bb.array()[0]) & 0xff)); System.out.println("byte buffer content: " + ((bb.array()[1]) & 0xff)); System.out.println("byte buffer content: " + ((bb.array()[2]) & 0xff)); session.getBasicRemote().sendBinary(bb, last); } } catch (IOException e) { try { session.close(); } catch (IOException e1) { // Ignore } } } }
如何在tomcat中啟動websocket服務(wù)器,首先需要在web.xml添加如下配置:
[listener] [listener-class]org.apache.tomcat.websocket.server.WsContextListener[/listener-class] [/listener]
然后實現(xiàn)ServerApplicationConfig接口,實現(xiàn)如下:
創(chuàng)建網(wǎng)頁echo.html,內(nèi)容如下:
[html] [head] [title>Web Socket Echo Test[/title] [script] var ws = null; var count = 0; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('echo').disabled = !connected; } function connect() { var target = document.getElementById('target').value; if (target == '') { alert('Please select server side connection implementation.'); return; } if ('WebSocket' in window) { ws = new WebSocket(target); } else if ('MozWebSocket' in window) { ws = new MozWebSocket(target); } else { alert('WebSocket is not supported by this browser.'); return; } ws.onopen = function () { setConnected(true); log('Info: WebSocket connection opened.'); }; ws.onmessage = function (event) { log('Received: ' + event.data);