新西兰服务器

Java中Spring WebSocket详解


Java中Spring WebSocket详解

发布时间:2020-10-09 04:02:47 来源:脚本之家 阅读:85 作者:laozhang 栏目:编程语言

首先 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

前端的测试页面 mainresourcesstaticindex.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="external nofollow" rel="stylesheet">   <!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="external nofollow" 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">    <h2>WebSocket Test Page</h2>    <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"  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 进行前后端的通信了,如果大家还有不明白的或者有更好的方法,可以在下方的留言区讨论。

[微信提示:高防服务器能助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

[图文来源于网络,不代表本站立场,如有侵权,请联系高防服务器网删除]
[