在Java代码中使用Spring WebSocket


声明:本文转载自https://my.oschina.net/Kxvz/blog/1591764,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

首先 pom.xml

<parent> 	<groupId>org.springframework.boot</groupId> 	<artifactId>spring-boot-starter-parent</artifactId> 	<version>1.5.8.RELEASE</version> </parent>  	  <dependency> 	<groupId>org.apache.commons</groupId> 	<artifactId>commons-io</artifactId> </dependency> <dependency> 	<groupId>javax.websocket</groupId> 	<artifactId>javax.websocket-api</artifactId> 	<version>1.0</version> 	<scope>provided</scope> </dependency> <dependency> 	<groupId>org.springframework</groupId> 	<artifactId>spring-websocket</artifactId> </dependency> <dependency> 	<groupId>org.springframework.boot</groupId> 	<artifactId>spring-boot-starter-web</artifactId> 	<exclusions> 		<exclusion> 			<groupId>org.springframework.boot</groupId> 			<artifactId>spring-boot-starter-tomcat</artifactId> 		</exclusion> 	</exclusions> </dependency> <dependency> 	<groupId>org.springframework.boot</groupId> 	<artifactId>spring-boot-starter-undertow</artifactId> </dependency>

 

接收消息后的处理类 GameHandler :

import java.net.URI; import org.springframework.web.socket.BinaryMessage; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.PongMessage; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.AbstractWebSocketHandler;  public class GameHandler extends AbstractWebSocketHandler {      /**      * 处理字符串类的信息      *      * @param session      * @param message      * @throws Exception      */     @Override     protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {         session.sendMessage(new TextMessage(message.asBytes()));     }      /**      * 处理二进制类的信息      *      * @param session      * @param message      * @throws Exception      */     @Override     protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {         session.sendMessage(new BinaryMessage(message.getPayload()));     }      /**      * ping-pong      *      * @param session      * @param message      * @throws Exception      */     @Override     protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception { 	     }      /**      * 传出错误的处理      *      * @param session      * @param exception      * @throws Exception      */     @Override     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { 	     }      /**      * 连接关闭的处理      *      * @param session      * @param status      * @throws Exception      */     @Override     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {     }      /**      * 连接建立后的处理      *      * @param session      * @throws Exception      */     @Override     public void afterConnectionEstablished(WebSocketSession session) throws Exception { 	     } } 

 

握手信息拦截器  WebSocketHandshakeInterceptor :

import java.util.Map; import javax.servlet.http.Cookie; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor;   public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {      @Override     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse shr1, WebSocketHandler wsh, Map<String, Object> attributes) throws Exception {         // 此处可以做一些权限认证的事情或者其他         return true;     }      @Override     public void afterHandshake(ServerHttpRequest shr, ServerHttpResponse shr1, WebSocketHandler wsh, Exception excptn) { 	     } } 

 

使用WebSocket的配置类  WebSocketConfig :

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;   @Configuration @EnableWebSocket public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {      @Override     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {         // 允许连接的域,只能以http或https开头         String[] allowsOrigins = {"http://127.0.0.1:1213", "http://localhost:1213"};         registry.addHandler(gameHandler(),"/game").addInterceptors(handshakeInterceptor()).setAllowedOrigins(allowsOrigins);     }      @Bean     public GameHandler gameHandler() {         return new GameHandler();     }      @Bean     public WebSocketHandshakeInterceptor handshakeInterceptor() {         return new WebSocketHandshakeInterceptor();     } } 

 

启动类 Launcher  : 

@SpringBootApplication public class Launcher {      public static void main(String[] params) {         SpringApplication.run(Launcher.class, params); 	} }

 

配置文件 main/resources/application.properties:

server.port=1213 server.session-timeout=1800 server.undertow.io-threads=4 server.undertow.worker-threads=20 server.undertow.buffer-size=1024 server.undertow.buffers-per-region=1024 server.undertow.direct-buffers=true

 

前端的测试页面 main\resources\static\index.html

<!DOCTYPE html> <html lang="zh-CN">     <head>         <meta charset="utf-8">         <meta http-equiv="X-UA-Compatible" content="IE=edge">         <meta name="viewport" content="width=device-width, initial-scale=1">         <title>Platform Gateway</title>         <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">         <!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet">-->         <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>         <script src="https://cdn.bootcss.com/jquery-scrollTo/2.1.2/jquery.scrollTo.min.js"></script>         <script src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.6/pako.min.js"></script>         <!--[if lt IE 9]>           <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>           <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>         <![endif]-->         <style>             #message{                 height: 600px;                 overflow-y:auto;             }         </style>     </head>     <body>         <div class="container">             <h1>WebSocket Test Page</h1>             <hr/>             <div class="form-inline">                 <div class="form-group">                     <label for="wsAddr">WebSocket Address: </label>                     <div class="input-group">                         <span class="input-group-addon" id="basic-ws">ws://127.0.0.1:1213/</span>                         <input type="text" class="form-control" id="basic-ws-addr" aria-describedby="basic-ws" placeholder="game" data-container="body"  data-placement="top" data-content="链接地址不能为空,请填写">                     </div>                 </div>                 <button type="button" id="btnConnect" class="btn btn-primary" onclick="connect();">                     <span class="glyphicon glyphicon-resize-small" aria-hidden="true"></span>                     连接                 </button>                 <button type="button" id="btnClose" class="btn btn-danger" disabled="disabled" onclick="closeWebSocket();">                     <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>                     断开                 </button>                 <button type="button" id="btnSend" class="btn btn-info" disabled="disabled" style="margin-left: 50px;" onclick="send();">                     <span class="glyphicon glyphicon-transfer" aria-hidden="true"></span>                     发送消息                 </button>             </div><br/>             <textarea class="form-control" id="inMsg" rows="5" placeholder="在这里输入需要发送的信息..."></textarea>             <hr/>             <div id="message"></div>         </div>         <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>         <script type="text/javascript">                     function zip(str) {                         var binaryString = pako.gzip(str, {to: 'string'});                         return btoa(binaryString);                     }                      function unzip(b64Data) {                         var strData = atob(b64Data);                         var charData = strData.split('').map(function (x) {                             return x.charCodeAt(0);                         });                         var binData = new Uint8Array(charData);                         var data = pako.inflate(binData);                         strData = String.fromCharCode.apply(null, new Uint16Array(data));                         return strData;                     }                      var websocket = null;                     var wsBaseUrl = null;                     var wsUrl = null;                     function init() {                         wsBaseUrl = "ws://" + window.location.host + "/";                         $("#basic-ws").text(wsBaseUrl);                         $(function () {                             $('[data-toggle="popover"]').popover();                         });                         return false;                     } //关闭WebSocket连接                     function closeWebSocket() {                         if (websocket) {                             websocket.close();                         }                         return false;                     }  //将消息显示在网页上                     function setMessageInnerHTML(who, msg) {                         var message = null;                         if (who === 1) {                             message = '<div class="alert alert-success" role="alert">本地: ' + msg + '</div>';                         } else {                             message = '<div class="alert alert-info" role="alert">服务器: ' + msg + '</div>';                         }                         document.getElementById('message').innerHTML = (document.getElementById('message').innerHTML + message);                         $("#message").scrollTo('100%');                         return false;                     }  //发送消息                     function send() {                         if (websocket) {                             var message = $("#inMsg").val();                             websocket.send(zip(message));                             setMessageInnerHTML(1, message);                         }                         return false;                     }                     function connect() {                         var url = $("#basic-ws-addr").val();                         if (url.length <= 0) {                             $('#basic-ws-addr').popover('show');                             setTimeout(function () {                                 $('#basic-ws-addr').popover('hide');                             }, 3000);                         } else {                             wsUrl = wsBaseUrl + url;                             if ('WebSocket' in window) {                                 websocket = new WebSocket(wsUrl);                                 //连接发生错误的回调方法                                 websocket.onerror = function () {                                     setMessageInnerHTML(0, "WebSocket连接发生错误 -> " + wsUrl);                                     $("#btnConnect").removeAttr("disabled");                                     $("#btnClose").attr("disabled", "disabled");                                     $("#btnSend").attr("disabled", "disabled");                                 };                                  //连接成功建立的回调方法                                 websocket.onopen = function () {                                     setMessageInnerHTML(0, "WebSocket连接成功 -> " + wsUrl);                                     $("#btnConnect").attr("disabled", "disabled");                                     $("#btnClose").removeAttr("disabled");                                     $("#btnSend").removeAttr("disabled");                                 };                                  //接收到消息的回调方法                                 websocket.onmessage = function (event) {                                     setMessageInnerHTML(0, unzip(event.data));                                 };                                  //连接关闭的回调方法                                 websocket.onclose = function () {                                     setMessageInnerHTML(0, "WebSocket连接关闭 -> " + wsUrl);                                     $("#btnConnect").removeAttr("disabled");                                     $("#btnClose").attr("disabled", "disabled");                                     $("#btnSend").attr("disabled", "disabled");                                 };                                  //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。                                 window.onbeforeunload = function () {                                     closeWebSocket();                                 };                             } else {                                 alert('Not support websocket');                             }                         }                         return false;                     }                     window.onload = init();         </script>     </body> </html>

 

到此就可以使用 WebSocket 进行前后端的通信了,Good Luck.

本文发表于2017年12月19日 14:33
(c)注:本文转载自https://my.oschina.net/Kxvz/blog/1591764,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2055 讨论 1 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1