zoukankan      html  css  js  c++  java
  • Spring Boot对WebSocket整合

    SpringBoot本身不提供WebSocket支持,还是需要服务器如内嵌的Tomcat对WebSocket的支持。

    引入maven依赖:

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-json</artifactId>
            </dependency>

    引入Spring Boot对WebSocket依赖实际上是Spring对WebSocket的支持:

    客户端这里使用Sockjs,非原生的websocket支持的js API,这样做的好处是,对不支持WebSocket的浏览器可以自动降级。使用轮询的方式来访问服务端。

    https://github.com/sockjs/sockjs-client

    cdn加速:https://www.bootcdn.cn/sockjs-client/

     HTML  echo.html代码:

      1 <!DOCTYPE html>
      2 <html>
      3     <head>
      4         <title>WebSocket Simple</title>
      5         <style type="text/css">
      6             #connect-container {
      7                 float: left;
      8                 width: 400px;
      9             }
     10 
     11             #connect-container div {
     12                 padding: 5px;
     13             }
     14 
     15             #console-container {
     16                 float: left;
     17                 margin-left: 15px;
     18                 width: 400px;
     19             }
     20 
     21             #console {
     22                 border: 1px solid #CCCCCC;
     23                 border-right-color: #999999;
     24                 border-bottom-color: #999999;
     25                 height: 170px;
     26                 overflow-y: scroll;
     27                 padding: 5px;
     28                 width: 100%;
     29             }
     30 
     31             #console p {
     32                 padding: 0;
     33                 margin: 0;
     34             }
     35         </style>
     36         <script src="https://cdn.bootcss.com/sockjs-client/0.3.4/sockjs.min.js"></script>
     37         <script type="text/javascript">
     38             var ws = null;
     39 
     40             function setConnected(connected) {
     41                 document.getElementById('connect').disabled = connected;
     42                 document.getElementById('disconnect').disabled = !connected;
     43                 document.getElementById('echo').disabled = !connected;
     44             }
     45 
     46             function connect() {
     47                 var target  = document.getElementById('target').value;
     48                 ws = new SockJS(target);
     49                 ws.onopen = function () {
     50                     setConnected(true);
     51                     log('Info: WebSocket connection opened.');
     52                 };
     53                 ws.onmessage = function (event) {
     54                     log('Received:' + event.data);
     55                 };
     56                 ws.onclose = function () {
     57                     setConnected(false);
     58                     log('Info: WebSocket connection closed.')
     59                 }
     60             }
     61 
     62             function disconnect() {
     63                 if(ws != null){
     64                     ws.close();
     65                     ws = null;
     66                 }
     67                 setConnected(false);
     68             }
     69 
     70             function echo() {
     71                 if(ws != null){
     72                     var message = document.getElementById('message').value;
     73                     log('Send:' + message);
     74                     ws.send(message);
     75                 }else{
     76                     alert('WebSocket connection not established , plase connect.');
     77                 }
     78             }
     79 
     80             function log(message) {
     81                 var console = document.getElementById('console');
     82                 console.appendChild(document.createTextNode('<p>'+message+'</p>'));
     83                 while(console.childNodes.length > 25){
     84                     console.removeChild(console.firstChild);
     85                 }
     86                 console.scrollTop = console.scrollHeight;
     87             }
     88         </script>
     89     </head>
     90     <body>
     91         <noscript>
     92             <h2 >............................................... </h2>
     93         </noscript>
     94         <div>
     95             <div id="connect-container">
     96                 <div>
     97                     <input id="target" type="text" size="40" style="" value="/echo"/>
     98                 </div>
     99                 <div>
    100                     <button id = "connect" onclick="connect();">Connect</button>
    101                     <button id="disconnect" onclick="disconnect();" disabled="disabled">Disconnect</button>
    102                 </div>
    103                 <div>
    104                     <textarea id="message" >a message to be sent</textarea>
    105                 </div>
    106                 <div>
    107                     <button id="echo" onclick="echo();" disabled="disabled">Echo message</button>
    108                 </div>
    109             </div>
    110             <div id="console-container">
    111                 <div id="console"></div>
    112             </div>
    113         </div>
    114     </body>
    115 </html>
    View Code

    下面Spring Boot编写服务端代码:

    首先定义一个业务接口,获取消息:

    public interface EchoService {
         String   getMessage(String message);
    }

    然后提供一个业务接口的实现类:

    public class DefaultEchoService implements EchoService {
    
        private final String echoFormat;
    
        public DefaultEchoService(String echoFormat) {
            this.echoFormat = (null != echoFormat)?echoFormat:"%s";
        }
    
        @Override
        public String getMessage(String message) {
            return String.format(echoFormat,message);
        }
    }

    然后继承一个websocket消息处理的handler(类似于netty对websocket的处理):TextWebSocketHandler

    public class EchoWebSocketHandler extends TextWebSocketHandler {
    
        private EchoService echoService;
    
        public EchoWebSocketHandler(EchoService echoService) {
            this.echoService = echoService;
        }
    
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            System.out.println("连接建立");
        }
    
        /**
         * 类似于Netty的Channel
         * @param session
         * @param exception
         * @throws Exception
         */
        @Override
        public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
            session.close(CloseStatus.SERVER_ERROR);
        }
    
        @Override
        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
            String echoMessage = this.echoService.getMessage(message.getPayload());
            //消息重新发回给客户端
            session.sendMessage(new TextMessage(echoMessage));
        }
    }

    继承关系类图如下,典型的适配器模式:

      最后在启动类实现WebSocketConfigurer接口,然后把自己实现的EchoWebSocketHandler注册进去

    @SpringBootApplication
    @EnableWebSocket //非常重要,不然不会启用websocket功能
    public class SpringbootDemoApplication implements WebSocketConfigurer { private static final Logger logger = LoggerFactory.getLogger(SpringbootDemoApplication.class); public static void main(String[] args) { SpringApplication.run(SpringbootDemoApplication.class, args); } @PostConstruct public void myLog(){ logger.trace("trace Message"); logger.debug("debug Message"); logger.info("info Message"); logger.warn("warn Message"); logger.error("error Message"); } /** * 注册websocket的处理器:EchoWebSocketHandler * @param registry */ @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(echoWebSocketHandler(),"/echo").withSockJS(); } /** * 实例化 * @return */ @Bean public EchoService echoService(){ return new DefaultEchoService(" output message: "%s"! "); } @Bean public WebSocketHandler echoWebSocketHandler(){ return new EchoWebSocketHandler(echoService()); } }

     测试验证:

    访问:http://localhost:8090/echo.html 页面代码

    Status Code  101 代表协议转换,Http升级成WebSocket协议

     

     

  • 相关阅读:
    Winfrom 减少控件重绘闪烁的方法
    Blazor client-side Preview 预览版 如何调试 Debug
    实用,Windows后台守护进程iNeuDaemon发布。Linux操作系统下使用使用supervisor
    RabbitMQ消息队列之Windows下安装和部署(一)
    Angularjs接收服务端的布尔值
    python基础教程:浅谈python for循环的巧妙运用(迭代、列表生成式)
    Excel合并数据查找函数VLOOKUP()一直显示最后一行数据或者一直报错的解决方法
    RHCE(一)NFS服务详解——搭建与配置
    [WPF 自定义控件]在MenuItem上使用RadioButton
    EF CORE中复杂类型的映射
  • 原文地址:https://www.cnblogs.com/fubinhnust/p/12008180.html
Copyright © 2011-2022 走看看