WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。javascript
WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。css
在 WebSocket API 中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。html
如今,不少網站爲了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。java
HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。web
瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。spring
當你獲取 Web Socket 鏈接後,你能夠經過 send() 方法來向服務器發送數據,並經過 onmessage 事件來接收服務器返回的數據。express
如下 API 用於建立 WebSocket 對象。apache
var Socket = new WebSocket(url, [protocol] );
以上代碼中的第一個參數 url, 指定鏈接的 URL。第二個參數 protocol 是可選的,指定了可接受的子協議。api
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>WebSocket測試</title> 6 </head> 7 <body style="text-align: center;"> 8 <h2>WebSocket測試</h2> 9 <div> 10 <input type="text" id="txt"/> 11 <button onclick="sendWebSocket()">發送</button><br> 12 <button onclick="checkWebSocket()">測試WebSocket</button> 13 <button onclick="connectWebSocket()">鏈接WebSocket</button> 14 <button onclick="closeWebSocket()">關閉WebSocket</button><br> 15 <hr> 16 <div id="message"></div> 17 </div> 18 </body> 19 <script type="text/javascript"> 20 21 var websocket = null; 22 23 function checkWebSocket(){ 24 if ("WebSocket" in window) { 25 // alert("您的瀏覽器支持 WebSocket!"); 26 setMessageInnerHTML("您的瀏覽器支持 WebSocket!"); 27 } 28 else { 29 // 瀏覽器不支持 WebSocket 30 // alert("您的瀏覽器不支持 WebSocket!"); 31 setMessageInnerHTML("您的瀏覽器不支持 WebSocket!"); 32 } 33 } 34 35 // 鏈接 WebSocket 36 function connectWebSocket(){ 37 // 打開一個 web socket 38 websocket = new WebSocket("ws://localhost:8080/test-websocket/websocket"); 39 websocket.onopen = function() { 40 // Web Socket 已鏈接上,使用 send() 方法發送數據 41 setMessageInnerHTML("WebSocket 已鏈接..."); 42 }; 43 websocket.onmessage = function(evt) { 44 var received_msg = evt.data; 45 setMessageInnerHTML("收到消息:" + received_msg); 46 }; 47 websocket.onclose = function() 48 { 49 setMessageInnerHTML("WebSocket 已關閉..."); 50 }; 51 } 52 53 // 向WebSocket服務端發送消息 54 function sendWebSocket(){ 55 if (websocket){ 56 if (websocket.readyState == websocket.OPEN) { 57 var message = document.getElementById('txt').value; 58 websocket.send(message); 59 } else { 60 setMessageInnerHTML("WebSocket 未鏈接..."); 61 } 62 }else { 63 setMessageInnerHTML("WebSocket 未建立..."); 64 } 65 } 66 67 // 監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket鏈接,防止鏈接還沒斷開就關閉窗口,server端會拋異常。 68 window.onbeforeunload = function() { 69 closeWebSocket(); 70 } 71 72 // 關閉WebSocket鏈接 73 function closeWebSocket() { 74 websocket.close(); 75 } 76 77 // 將消息顯示在網頁上 78 function setMessageInnerHTML(innerHTML) { 79 document.getElementById('message').innerHTML += innerHTML + '<br/>'; 80 } 81 </script> 82 </html>
java 實現websocket的兩種方式,一種使用tomcat的websocket實現,一種使用spring的websocket瀏覽器
一、新建一個Maven Web工程,參考:【Maven】Eclipse 使用Maven建立Java Web項目,添加websocket依賴以下:
<dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency>
二、編輯一個WebSocket服務端類,MyWebSocket.class
1 package com.test.websocket; 2 3 import java.io.IOException; 4 5 import javax.websocket.OnClose; 6 import javax.websocket.OnError; 7 import javax.websocket.OnMessage; 8 import javax.websocket.OnOpen; 9 import javax.websocket.Session; 10 import javax.websocket.server.ServerEndpoint; 11 12 @ServerEndpoint("/websocket") 13 public class MyWebSocket { 14 15 private Session session; 16 17 /** 18 * 鏈接創建後觸發的方法 19 */ 20 @OnOpen 21 public void onOpen(Session session) { 22 this.session = session; 23 WebSocketMapUtil.put(session.getId(), this); 24 System.out.println("-------- onOpen: 當前在線人數 " + WebSocketMapUtil.getOnlineCount() + ",鏈接人 " + session.getId() + " --------"); 25 } 26 27 /** 28 * 鏈接關閉後觸發的方法 29 */ 30 @OnClose 31 public void onClose() { 32 // 從map中刪除 33 WebSocketMapUtil.remove(session.getId()); 34 System.out.println("-------- onClose: 當前在線人數 " + WebSocketMapUtil.getOnlineCount() + ",關閉人 " + session.getId() + " --------"); 35 } 36 37 /** 38 * 接收到客戶端消息時觸發的方法 39 */ 40 @OnMessage 41 public void onMessage(String message, Session session) throws Exception { 42 // 獲取服務端到客戶端的通道 43 MyWebSocket myWebSocket = WebSocketMapUtil.get(session.getId()); 44 System.out.println("收到來自 " + session.getId() + " 的消息:" + message); 45 46 // 返回消息給Web Socket客戶端(瀏覽器) 47 myWebSocket.sendMessageAll("服務端已收到消息:" + message); 48 } 49 50 /** 51 * 發生錯誤時觸發的方法 52 */ 53 @OnError 54 public void onError(Session session, Throwable error) { 55 System.out.println("-------- onError: 當前在線人數 " + WebSocketMapUtil.getOnlineCount() + ",鏈接發生錯誤 " + session.getId() + "-"+ error.getMessage() + " --------"); 56 // error.printStackTrace(); 57 } 58 59 /** 60 * 給單個客戶端發送消息 61 * @param message 62 * @param sessionId 63 * @throws IOException 64 */ 65 public void sendMessageSingle(String message, String sessionId) throws IOException { 66 67 // session.getBasicRemote().sendText(message); 同步消息 68 // session.getAsyncRemote().sendText(message); 異步消息 69 70 MyWebSocket myWebSocket = WebSocketMapUtil.get(sessionId); 71 if(myWebSocket != null) { 72 myWebSocket.session.getBasicRemote().sendText(message); 73 } 74 } 75 76 /** 77 * 給全部客戶端發送消息 78 * @param message 79 * @throws IOException 80 */ 81 public void sendMessageAll(String message) throws IOException { 82 for (MyWebSocket item : WebSocketMapUtil.getValues() ) { 83 item.session.getAsyncRemote().sendText(message); 84 System.out.println(item.session.getId()); 85 System.out.println(item.session.isSecure()); 86 System.out.println(item.session.isOpen()); 87 } 88 } 89 90 }
三、編輯一個WebSocket 工具類,WebSocketMapUtil.class
1 package com.test.websocket; 2 3 import java.util.Collection; 4 import java.util.concurrent.ConcurrentHashMap; 5 import java.util.concurrent.ConcurrentMap; 6 7 public class WebSocketMapUtil { 8 9 public static ConcurrentMap<String, MyWebSocket> webSocketMap = new ConcurrentHashMap<>(); 10 11 public static void put(String key, MyWebSocket myWebSocket) { 12 webSocketMap.put(key, myWebSocket); 13 } 14 15 public static MyWebSocket get(String key) { 16 return webSocketMap.get(key); 17 } 18 19 public static void remove(String key) { 20 webSocketMap.remove(key); 21 } 22 23 public static Collection<MyWebSocket> getValues() { 24 return webSocketMap.values(); 25 } 26 27 public static int getOnlineCount() { 28 return webSocketMap.size(); 29 } 30 }
四、將項目發佈到Tomcat中,使用瀏覽器訪問界面(http://127.0.0.1:8080/test-websocket/static/websocket.html)
界面輸出以下:
服務端輸出以下:
一、新建一個Maven Web工程,參考:【Maven】Eclipse 使用Maven建立SpringMVC Web項目,添加Spring-Websocket依賴以下:
1 <!--Spring WebSocket --> 2 <dependency> 3 <groupId>org.springframework</groupId> 4 <artifactId>spring-websocket</artifactId> 5 <version>4.3.13.RELEASE</version> 6 </dependency>
1 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <groupId>com.test</groupId> 6 <artifactId>test-websocket</artifactId> 7 <packaging>war</packaging> 8 <version>0.0.1-SNAPSHOT</version> 9 <name>test-websocket Maven Webapp</name> 10 <url>http://maven.apache.org</url> 11 12 <!-- 定義maven變量 --> 13 <properties> 14 <!-- spring --> 15 <spring.version>5.0.0.RELEASE</spring.version> 16 17 <!-- log --> 18 <commons-logging.version>1.1.3</commons-logging.version> 19 20 <!-- Servlet --> 21 <servlet.version>3.0.1</servlet.version> 22 <jsp-api.version>2.2</jsp-api.version> 23 24 <!-- jstl --> 25 <jstl.version>1.2</jstl.version> 26 <standard.version>1.1.2</standard.version> 27 28 <!-- test --> 29 <junit.version>3.8.1</junit.version> 30 31 <!-- jdk --> 32 <jdk.version>1.7</jdk.version> 33 <maven.compiler.plugin.version>2.3.2</maven.compiler.plugin.version> 34 </properties> 35 36 37 <dependencies> 38 <!--Spring WebSocket --> 39 <dependency> 40 <groupId>org.springframework</groupId> 41 <artifactId>spring-websocket</artifactId> 42 <version>4.3.13.RELEASE</version> 43 </dependency> 44 45 <dependency> 46 <groupId>javax.websocket</groupId> 47 <artifactId>javax.websocket-api</artifactId> 48 <version>1.1</version> 49 <scope>provided</scope> 50 </dependency> 51 52 <dependency> 53 <groupId>org.java-websocket</groupId> 54 <artifactId>Java-WebSocket</artifactId> 55 <version>1.4.0</version> 56 </dependency> 57 58 <dependency> 59 <groupId>org.springframework</groupId> 60 <artifactId>spring-core</artifactId> 61 <version>${spring.version}</version> 62 </dependency> 63 64 <dependency> 65 <groupId>org.springframework</groupId> 66 <artifactId>spring-beans</artifactId> 67 <version>${spring.version}</version> 68 </dependency> 69 70 <dependency> 71 <groupId>org.springframework</groupId> 72 <artifactId>spring-context</artifactId> 73 <version>${spring.version}</version> 74 </dependency> 75 76 <dependency> 77 <groupId>org.springframework</groupId> 78 <artifactId>spring-jdbc</artifactId> 79 <version>${spring.version}</version> 80 </dependency> 81 82 83 <dependency> 84 <groupId>org.springframework</groupId> 85 <artifactId>spring-expression</artifactId> 86 <version>${spring.version}</version> 87 </dependency> 88 89 <dependency> 90 <groupId>org.springframework</groupId> 91 <artifactId>spring-web</artifactId> 92 <version>${spring.version}</version> 93 </dependency> 94 95 <dependency> 96 <groupId>org.springframework</groupId> 97 <artifactId>spring-webmvc</artifactId> 98 <version>${spring.version}</version> 99 </dependency> 100 101 <dependency> 102 <groupId>org.springframework</groupId> 103 <artifactId>spring-tx</artifactId> 104 <version>${spring.version}</version> 105 </dependency> 106 107 108 <!-- Servlet --> 109 <dependency> 110 <groupId>javax.servlet</groupId> 111 <artifactId>javax.servlet-api</artifactId> 112 <version>${servlet.version}</version> 113 <scope>provided</scope> 114 </dependency> 115 <dependency> 116 <groupId>javax.servlet.jsp</groupId> 117 <artifactId>jsp-api</artifactId> 118 <version>${jsp-api.version}</version> 119 <scope>provided</scope> 120 </dependency> 121 122 <!-- jstl --> 123 <dependency> 124 <groupId>javax.servlet</groupId> 125 <artifactId>jstl</artifactId> 126 <version>${jstl.version}</version> 127 </dependency> 128 129 <dependency> 130 <groupId>taglibs</groupId> 131 <artifactId>standard</artifactId> 132 <version>${standard.version}</version> 133 </dependency> 134 135 <!-- test --> 136 <dependency> 137 <groupId>junit</groupId> 138 <artifactId>junit</artifactId> 139 <version>${junit.version}</version> 140 <scope>test</scope> 141 </dependency> 142 143 144 <dependency> 145 <groupId>org.slf4j</groupId> 146 <artifactId>slf4j-api</artifactId> 147 <version>1.7.5</version> 148 <type>jar</type> 149 <scope>compile</scope> 150 </dependency> 151 152 <dependency> 153 <groupId>ch.qos.logback</groupId> 154 <artifactId>logback-core</artifactId> 155 <version>0.9.30</version> 156 <type>jar</type> 157 </dependency> 158 159 <dependency> 160 <groupId>ch.qos.logback</groupId> 161 <artifactId>logback-classic</artifactId> 162 <version>0.9.30</version> 163 <type>jar</type> 164 </dependency> 165 166 <dependency> 167 <groupId>ch.qos.logback</groupId> 168 <artifactId>logback-access</artifactId> 169 <version>0.9.30</version> 170 </dependency> 171 172 </dependencies> 173 174 175 <build> 176 <plugins> 177 <!-- define the project compile level --> 178 <plugin> 179 <groupId>org.apache.maven.plugins</groupId> 180 <artifactId>maven-compiler-plugin</artifactId> 181 <version>${maven.compiler.plugin.version}</version> 182 <configuration> 183 <source>${jdk.version}</source> 184 <target>${jdk.version}</target> 185 </configuration> 186 </plugin> 187 </plugins> 188 <finalName>test-websocket</finalName> 189 </build> 190 191 192 </project>
二、新建一個websocket消息處理類,MyWebSocketHandler.java
1 package com.test.socket.handler; 2 3 import java.io.IOException; 4 5 import org.springframework.web.socket.CloseStatus; 6 import org.springframework.web.socket.TextMessage; 7 import org.springframework.web.socket.WebSocketSession; 8 import org.springframework.web.socket.handler.AbstractWebSocketHandler; 9 10 11 public class MyWebSocketHandler extends AbstractWebSocketHandler { 12 13 @Override 14 public void afterConnectionEstablished(WebSocketSession session) { 15 WebSocketHandlerUtil.put(session.getId(), session); 16 System.out.println("-------- onOpen: 當前在線人數 " + WebSocketHandlerUtil.getOnlineCount() + ",鏈接人 " 17 + session.getId() + " --------"); 18 } 19 20 21 @Override 22 public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) { 23 // 從map中刪除 24 WebSocketHandlerUtil.remove(session.getId()); 25 System.out.println("-------- onClose: 當前在線人數 " + WebSocketHandlerUtil.getOnlineCount() + ",關閉人 " + session.getId() + " --------"); 26 } 27 28 29 /** 30 * 在UI在用js調用websocket.send()時候,會調用該方法 31 */ 32 @Override 33 protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { 34 // super.handleTextMessage(session, message); 35 // 獲取服務端到客戶端的通道 36 System.out.println("收到來自 " + session.getId() + " 的消息:" + message.getPayload()); 37 38 // 返回消息給Web Socket客戶端(瀏覽器) 39 sendMessageAll("服務端已收到消息:" + message); 40 } 41 42 /** 43 * 發生錯誤時觸發的方法 44 */ 45 @Override 46 public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { 47 if (session.isOpen()) { 48 session.close(); 49 } 50 System.out.println("-------- onError: 當前在線人數 " + WebSocketHandlerUtil.getOnlineCount() + ",鏈接發生錯誤 " + session.getId() + "-"+ exception.getMessage() + " --------"); 51 } 52 53 /** 54 * 給單個客戶端發送消息 55 * @param message 56 * @param sessionId 57 * @throws IOException 58 */ 59 public void sendMessageSingle(String message, String sessionId) throws IOException { 60 61 WebSocketSession session = WebSocketHandlerUtil.get(sessionId); 62 if(session != null) { 63 session.sendMessage(new TextMessage(message)); 64 } 65 } 66 67 /** 68 * 給全部客戶端發送消息 69 * @param message 70 * @throws IOException 71 */ 72 public void sendMessageAll(String message) throws IOException { 73 for (WebSocketSession session : WebSocketHandlerUtil.getValues() ) { 74 75 session.sendMessage(new TextMessage(message)); 76 } 77 } 78 79 }
三、WebSocketHandlerUtil.java,工具類
1 package com.test.socket.handler; 2 3 import java.util.Collection; 4 import java.util.concurrent.ConcurrentHashMap; 5 import java.util.concurrent.ConcurrentMap; 6 7 import org.springframework.web.socket.WebSocketSession; 8 9 public class WebSocketHandlerUtil { 10 11 public static ConcurrentMap<String, WebSocketSession> webSocketMap = new ConcurrentHashMap<>(); 12 13 public static void put(String key, WebSocketSession webSocketSession) { 14 webSocketMap.put(key, webSocketSession); 15 } 16 17 public static WebSocketSession get(String key) { 18 return webSocketMap.get(key); 19 } 20 21 public static void remove(String key) { 22 webSocketMap.remove(key); 23 } 24 25 public static Collection<WebSocketSession> getValues() { 26 return webSocketMap.values(); 27 } 28 29 public static int getOnlineCount() { 30 return webSocketMap.size(); 31 } 32 }
四、新建一個攔截器,WebSocketHandshakeInterceptor.java ,能夠處理請求到達websocket前的邏輯
1 package com.test.socket.handler; 2 3 import java.util.Map; 4 5 import javax.servlet.http.HttpServletRequest; 6 7 import org.springframework.http.server.ServerHttpRequest; 8 import org.springframework.http.server.ServerHttpResponse; 9 import org.springframework.http.server.ServletServerHttpRequest; 10 import org.springframework.web.socket.WebSocketHandler; 11 import org.springframework.web.socket.server.HandshakeInterceptor; 12 13 14 public class WebSocketHandshakeInterceptor implements HandshakeInterceptor { 15 16 @Override 17 public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 18 Map<String, Object> attributes) throws Exception { 19 // 請求 進入WebSocket處理器,處理相關邏輯 20 return true; 21 } 22 23 @Override 24 public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, 25 Exception exception) { 26 // TODO Auto-generated method stub 27 28 } 29 30 }
五、WebSocket配置類,WebSocketConfig.java,須要讓SpringMvc掃描到這個類
1 package com.test.socket.handler; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.web.socket.config.annotation.EnableWebSocket; 6 import org.springframework.web.socket.config.annotation.WebSocketConfigurer; 7 import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistration; 8 import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; 9 10 @Configuration 11 @EnableWebSocket 12 public class WebSocketConfig implements WebSocketConfigurer { 13 14 /** 15 * 16 * @param registry 該對象能夠調用addHandler()來註冊信息處理器。 17 */ 18 @Override 19 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 20 WebSocketHandlerRegistration handler = registry.addHandler(myWebSocketHandler(), "/myWebSocket"); 21 handler.addInterceptors(webSocketHandshakeInterceptor()); // 聲明攔截器 22 handler.setAllowedOrigins("*"); // 聲明容許訪問的主機列表 23 } 24 25 @Bean 26 public MyWebSocketHandler myWebSocketHandler() { 27 return new MyWebSocketHandler(); 28 } 29 30 @Bean 31 public WebSocketHandshakeInterceptor webSocketHandshakeInterceptor() { 32 return new WebSocketHandshakeInterceptor(); 33 } 34 35 }
六、spring-mvc.xml,文件以下:
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:websocket="http://www.springframework.org/schema/websocket" 5 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" 6 xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd 9 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 10 http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd 11 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> 12 13 <!-- 自動掃描的包名 --> 14 <context:component-scan base-package="com.test.socket.handler" /> 15 16 <!-- 默認的註解映射的支持 --> 17 <mvc:annotation-driven> 18 <mvc:message-converters> 19 <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> 20 <bean 21 class="org.springframework.http.converter.ResourceHttpMessageConverter" /> 22 </mvc:message-converters> 23 </mvc:annotation-driven> 24 25 26 27 <!-- 視圖解釋類,定義跳轉的文件的先後綴 --> 28 <!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 29 <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" 30 /> <property name="prefix" value="/views/" /> <property name="suffix" value=".jsp" 31 /> <property name="requestContextAttribute" value="rc" /> </bean> --> 32 <bean id="viewResolver" 33 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 34 <property name="viewClass" 35 value="org.springframework.web.servlet.view.JstlView" /> 36 <property name="prefix" value="/view/" /> 37 <property name="suffix" value=".jsp" /> 38 </bean> 39 40 41 <!-- 攔截器 --> 42 <!-- <mvc:interceptors> <bean class="com.fpx.ce.foundation.preference.PreferenceChangeInterceptor" 43 /> <mvc:interceptor> <mvc:mapping path="/page/home"/> <bean class="com.fpx.ce.foundation.user.UserInterceptor" 44 /> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/service/**" /> 45 <bean class="com.fpx.ce.foundation.log.LogHandlerInterceptor" /> </mvc:interceptor> 46 <mvc:interceptor> <mvc:mapping path="/test/**" /> <mvc:mapping path="/service/**" 47 /> <bean class="com.lemon.finder.web.SharedRenderVariableInterceptor" /> 48 </mvc:interceptor> </mvc:interceptors> --> 49 50 51 <!-- 對靜態資源文件的訪問 方案一 (二選一) --> 52 <mvc:default-servlet-handler /> 53 54 <!-- 對靜態資源文件的訪問 方案二 (二選一) --> 55 <!-- <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/> 56 <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/> 57 <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/> --> 58 59 <!-- <bean id="myWebSocket" class="com.test.socket.handler.MyWebSocketHandler" /> 60 61 <websocket:handlers> 62 <websocket:mapping handler="myWebSocket" path="/myWebSocket"/> 63 </websocket:handlers> --> 64 65 </beans>
七、將項目發佈到Tomcat中,使用瀏覽器訪問界面(http://127.0.0.1:8080/test-websocket/static/websocket.html),將界面中WebSocket鏈接地址改成:ws://localhost:8080/test-websocket/myWebSocket
一、新建一個Java Maven項目,引入依賴
1 <dependency> 2 <groupId>org.java-websocket</groupId> 3 <artifactId>Java-WebSocket</artifactId> 4 <version>1.4.0</version> 5 </dependency>
二、編輯Java WebSocket類
1 package com.test.websocket; 2 3 import java.net.URI; 4 import java.net.URISyntaxException; 5 import java.util.Iterator; 6 7 import org.java_websocket.client.WebSocketClient; 8 import org.java_websocket.enums.ReadyState; 9 import org.java_websocket.handshake.ServerHandshake; 10 11 public class MyWebSocketClient extends WebSocketClient { 12 13 public MyWebSocketClient(URI serverUri) { 14 super(serverUri); 15 } 16 17 @Override 18 public void onOpen(ServerHandshake handshakedata) { 19 // TODO Auto-generated method stub 20 System.out.println("------ MyWebSocket onOpen ------"); 21 for (Iterator<String> it = handshakedata.iterateHttpFields(); it.hasNext();) { 22 String key = it.next(); 23 System.out.println(key + ":" + handshakedata.getFieldValue(key)); 24 } 25 } 26 27 @Override 28 public void onClose(int code, String reason, boolean remote) { 29 // TODO Auto-generated method stub 30 System.out.println("------ MyWebSocket onClose ------"); 31 } 32 33 @Override 34 public void onError(Exception ex) { 35 // TODO Auto-generated method stub 36 System.out.println("------ MyWebSocket onError ------"); 37 } 38 39 @Override 40 public void onMessage(String message) { 41 // TODO Auto-generated method stub 42 System.out.println("-------- 接收到服務端數據: " + message + "--------"); 43 } 44 45 public static void main(String[] arg0) throws URISyntaxException, InterruptedException { 46 MyWebSocketClient myClient = new MyWebSocketClient(new URI("ws://localhost:8080/test-websocket/myWebSocket")); 47 // 鏈接 48 myClient.connect(); 49 50 while (!myClient.getReadyState().equals(ReadyState.OPEN)) { 51 System.out.println("MyWebSocketClient 鏈接中 ..."); 52 } 53 54 // 往websocket服務端發送數據 55 myClient.send("MyWebSocketClient Message"); 56 57 // 調用此方法保持住鏈接 58 myClient.sendPing(); 59 60 Thread.sleep(3000); 61 myClient.close(); 62 } 63 }
三、測試,運行main方法