WebSocket協議定義了一種web應用的新功能,它實現了服務器端和客戶端的全雙工通訊。全雙工通訊即通訊的雙方能夠同時發送和接收信息 的信息交互方式。它是繼Java applets, XMLHttpRequest, Adobe Flash, ActiveXObject等使web應用更具交互性的新技術。javascript
在實現連線過程當中,瀏覽器和服務器經過TCP三次握手創建鏈接。 若是和服務器鏈接成功後,瀏覽器經過HTTP發送握手請求,若是服務器贊成握手鍊接,客戶端和服務端以後就能互相之間發送信息。HTTP只用於開始的握手,一旦成功創建握手鍊接,HTTP不會參與數據傳輸,使用TCP鏈接來傳輸數據。java
輪詢web
長輪詢就是客戶端按照一個固定的時間按期向服務器發送請求,一般這個時間間隔的長度受到服務端的更新頻率和客戶端處理更新數據時間的影響。這種方式缺點很明顯,就是瀏覽器要不斷髮請求到服務器以獲取最新信息,形成服務器壓力過大,佔用寬帶資源。ajax
使用streaming AJAXspring
streaming ajax是一種經過ajax實現的長鏈接維持機制。主要目的就是在數據傳輸過程當中對返回的數據進行讀取,而且不會關閉鏈接。api
iframe方式瀏覽器
iframe能夠在頁面中嵌套一個子頁面,經過將iframe的src指向一個長鏈接的請求地址,服務端就能不斷往客戶端傳輸數據。服務器
最適合websocket的web應用的就是那些客戶端和服務器端須要高頻繁、低延遲交換信息的應用。websocket
Spring提供了一個是適應於各類websocket引擎的websocket api,例如是Tomcat (7.0.47+)和GlassFish (4.0+),也適應於支持原生websocket的Jetty (9.0+)。而不一樣的瀏覽器對websocket的支持程度也有所不一樣,若是瀏覽器websocket不支持,那麼能夠用SocketJs代替websocket。session
建立和配置WebSocketHandler
WebSocketHandler用於處理websocket的消息。
public class MyHandler extends TextWebSocketHandler { @Override public void handleTextMessage(WebSocketSession session, TextMessage message) {
session.sendMessage(message); } }
建立和配置HandshakeInterceptor
HandshakeInterceptor
用於處理握手先後的預處理工做。
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor { @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { System.out.println("After Handshake"); super.afterHandshake(request, response, wsHandler, ex); } @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,Map<String, Object> attributes) throws Exception { System.out.println("Before Handshake");
return super.beforeHandshake(request, response, wsHandler, attributes); } }
同時配置spring-websocket.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> <websocket:handlers> <websocket:mapping handler="myHandler" path="/myHandler"/> <websocket:handshake-interceptors> <bean class="org.springframework.samples.HandshakeInterceptor"></bean> </websocket:handshake-interceptors> </websocket:handlers> <!--兼容低版本瀏覽器--> <websocket:handlers> <websocket:mapping handler="myHandler" path="/js/myHandler"/> <websocket:handshake-interceptors> <bean class="org.springframework.samples.HandshakeInterceptor"></bean> </websocket:handshake-interceptors> <websocket:sockjs /> </websocket:handlers> <bean id="myHandler" class="org.springframework.samples.MyHandler"></bean> </beans>
在頁面上添加JavaScript
<script type="text/javascript" src="js/sockjs.min.js"></script> <script type="text/javascript"> //websocket-demo是project name var sock=null; if (window['WebSocket']) { sock= new WebSocket('ws://' + window.location.host+'/websocket-demo/myHandler'); } else sock= new SockJS('/websocket-demo/js/myHandler');//兼容低版本瀏覽器 sock.onopen = function() { console.log('Opening'); sayHello(); }; sock.onmessage = function(e) { alert('Received message: '+ e.data); }; sock.onclose = function() { console.log('Closing'); }; function sayHello() { console.log('Sending Hello!'); sock.send("Hello!"); } </script>
若是要兼容低版本瀏覽器,還要在web.xml添加
<async-supported>true</async-supported>
須要注意的地方:
一、應用服務器的版本,若是版本太低是不支持websocket的
二、JavaScript的websocket的url應該和spring-websocket.xml的<websocket:mapping path="">一致
三、要兼容低版本瀏覽器,要使用web3.0,還有必須在一個請求涉及的全部Servlet及Filter中都聲明asyncSupported=true。