zoukankan      html  css  js  c++  java
  • SpringBoot2.x集成WebSocket

    WebSocket 不做过多得介绍,这里有篇比较全面得文章      Spring Boot系列十六 WebSocket简介和spring boot集成简单消息代理

    我这里是精简版,只挑出核心代码记录。免得浪费大家时间

    ⒈项目导入依赖

    1         <!-- 引入 websocket 依赖-->
    2         <dependency>
    3             <groupId>org.springframework.boot</groupId>
    4             <artifactId>spring-boot-starter-websocket</artifactId>
    5         </dependency>

    ⒉编写websocket配置

     1 package cn.coreqi.consumer.config;
     2 
     3 import org.springframework.context.annotation.Configuration;
     4 import org.springframework.messaging.simp.config.MessageBrokerRegistry;
     5 import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
     6 import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
     7 import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
     8 
     9 /**
    10  * 配置消息代理,默认情况下使用内置的消息代理。
    11  * @EnableWebSocketMessageBroker 此注解表示使用STOMP协议来传输基于消息代理的消息,此时可以在@Controller类中使用@MessageMapping
    12  */
    13 @Configuration
    14 @EnableWebSocketMessageBroker
    15 //SpringBoot2.x将extends AbstractWebSocketMessageBrokerConfigurer改为 implements WebSocketMessageBrokerConfigurer
    16 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    17     /**
    18      * 注册 Stomp的端点 配置对外暴露访问的端点
    19      * @param registry
    20      */
    21     @Override
    22     public void registerStompEndpoints(StompEndpointRegistry registry) {
    23         registry.addEndpoint("/websocket-simple")   //添加STOMP协议的端点。
    24                 // 这个URL是供WebSocket客户端或SockJS客户端连接服务端访问的地址。
    25                 .setAllowedOrigins("*") //添加允许跨域访问
    26                 .withSockJS();  //指定端点使用SockJS协议
    27     }
    28 
    29     /**
    30      * 配置消息代理
    31      * @param registry
    32      */
    33     @Override
    34     public void configureMessageBroker(MessageBrokerRegistry registry) {
    35         //启动简单Broker,客户端请求地址符合配置的前缀,消息才会发送到这个broker
    36         //客户端订阅当前服务端时需要添加以下请求前缀,topic一般用于广播推送,queue用于点对点推送
    37         registry.enableSimpleBroker("/userTest","/topicTest");
    38         //如果不设置下面这一句,使用SimpMessagingTemplate.convertAndSendToUser向指定用户推送消息时
    39         //订阅前缀只能为/user,例如前端订阅为/user/fanqi/info
    40         registry.setUserDestinationPrefix("/userTest");
    41         //客户端(html客户端、java客户端等)向服务端发送消息的请求前缀
    42         registry.setApplicationDestinationPrefixes("/app");
    43     }
    44 
    45 }

    ⒊编写控制器

     1 package cn.coreqi.consumer.controller;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.messaging.handler.annotation.MessageMapping;
     5 import org.springframework.messaging.handler.annotation.SendTo;
     6 import org.springframework.messaging.simp.SimpMessagingTemplate;
     7 import org.springframework.scheduling.annotation.EnableScheduling;
     8 import org.springframework.scheduling.annotation.Scheduled;
     9 import org.springframework.stereotype.Controller;
    10 import org.springframework.web.bind.annotation.RequestMapping;
    11 
    12 import java.text.DateFormat;
    13 import java.text.SimpleDateFormat;
    14 import java.util.Date;
    15 
    16 @Controller
    17 @EnableScheduling   //定时任务支持
    18 public class WebSocketController {
    19 
    20     @Autowired
    21     private SimpMessagingTemplate messagingTemplate;
    22 
    23 
    24     @RequestMapping("/")
    25     public String index() {
    26         return "index";
    27     }
    28 
    29     /**
    30      * 这里用于客户端推送消息到服务端,推送地址为:setApplicationDestinationPrefixes("/app")设置得前缀加上@MessageMapping注解得地址
    31      * 此处为/app/send
    32      * 当前方法处理后将结果转发给@SendTo注解得地址,如果没有指定,则采用默认
    33      * @MessageMapping 指定要接收消息的地址,类似@RequestMapping。除了注解到方法上,也可以注解到类上
    34      * @SendTo 默认消息将被发送到与传入消息相同的目的地,但是目的地前面附加前缀(默认情况下为"/topic")
    35      * @param message 客户端推送过来得消息,一般生产环境会封装
    36      * @return
    37      * @throws Exception
    38      */
    39     @MessageMapping("/send")
    40     @SendTo("/topicTest/web-to-server-to-web")
    41     public String greeting(String message) throws Exception {
    42         // 模拟延时,以便测试客户端是否在异步工作
    43         Thread.sleep(1000);
    44         return "Hello, " + message + "!";
    45     }
    46 
    47     /**
    48      * 最基本的服务器端主动推送消息给客户端
    49      * @return
    50      * @throws Exception
    51      */
    52     @Scheduled(initialDelay = 7000,fixedRate = 2000)
    53     public String serverTime() throws Exception {
    54         // 发现消息
    55         DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    56         messagingTemplate.convertAndSend("/topicTest/servertime", df.format(new Date()));
    57         return "servertime";
    58     }
    59 
    60     /**
    61      * 服务端推送消息到指定用户得客户端
    62      * 例如以下将会推送到
    63      * 因为设置了setUserDestinationPrefix("/userTest"),因此推送到/userTest/fanqi/info
    64      * 如果没有设置setUserDestinationPrefix(),则默认前端为user,将会推送到/user/fanqi/info
    65      * 客户端订阅/userTest/fanqi/info将会收到服务端推送得消息
    66      * @return
    67      * @throws Exception
    68      */
    69     @Scheduled(initialDelay = 7000,fixedRate = 2000)
    70     public String serverTimeToUser() throws Exception {
    71         DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    72         messagingTemplate.convertAndSendToUser("fanqi","/info", df.format(new Date()));
    73         return "serverTimeToUser";
    74     }
    75 }

    ⒋前端websocket客户端代码

      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4     <title>玩转spring boot——websocket</title>
      5     <script src="https://cdn.bootcss.com/angular.js/1.5.6/angular.min.js"></script>
      6     <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
      7     <script src="https://cdn.bootcss.com/sockjs-client/1.3.0/sockjs.js"></script>
      8     <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script>
      9     <script type="text/javascript">
     10         var stompClient = null;
     11 
     12         var app = angular.module('app', []);
     13         app.controller('MainController', function($rootScope, $scope, $http) {
     14 
     15             $scope.data = {
     16                 connected : false,
     17                 sendMessage : '',
     18                 receivMessages : []
     19             };
     20 
     21             //连接
     22             $scope.connect = function() {
     23                 var socket = new SockJS('/websocket-simple');
     24                 stompClient = Stomp.over(socket);
     25                 stompClient.connect({}, function(frame) {
     26                     // 订阅后端主动推消息到前端的topic
     27                     stompClient.subscribe('/topicTest/servertime', function(r) {
     28                         $scope.data.time = '当前服务器时间:' + r.body;
     29                         $scope.data.connected = true;
     30                         $scope.$apply();
     31                     });
     32                     // 阅后端主动推消息到前端的topic,只有指定的用户(hzb)收到的的消息
     33                     stompClient.subscribe('/userTest/fanqi/info', function(r) {
     34                         $scope.data.hzbtime = '当前服务器时间:' + r.body;
     35                         $scope.data.connected = true;
     36                         $scope.$apply();
     37                     });
     38                     // 订阅前端发到后台,后台又将消息返回前台的topic
     39                     stompClient.subscribe('/topicTest/web-to-server-to-web', function(msg) {
     40                         $scope.data.receivMessages.push(msg.body);
     41                         $scope.data.connected = true;
     42                         $scope.$apply();
     43                     });
     44 
     45 
     46                     $scope.data.connected = true;
     47                     $scope.$apply();
     48                 });
     49             };
     50 
     51             $scope.disconnect = function() {
     52                 if (stompClient != null) {
     53                     stompClient.disconnect();
     54                 }
     55                 $scope.data.connected = false;
     56             }
     57 
     58             $scope.send = function() {
     59                 stompClient.send("/app/send", {}, JSON.stringify({
     60                     'message' : $scope.data.sendMessage
     61                 }));
     62             }
     63         });
     64     </script>
     65 </head>
     66 <body ng-app="app" ng-controller="MainController">
     67 
     68 <h2>websocket示例</h2>
     69 <label>WebSocket连接状态:</label>
     70 <button type="button" ng-disabled="data.connected" ng-click="connect()">连接</button>
     71 <button type="button" ng-click="disconnect()" ng-disabled="!data.connected">断开</button>
     72 <br/>
     73 <br/>
     74 <div ng-show="data.connected">
     75     <h4>以下是websocket的服务端主动推送消息到页面的例子</h4>
     76     <label>{{data.time}}</label> <br/> <br/>
     77 </div>
     78 <div ng-show="data.connected">
     79     <h4>以下是websocket的服务端主动推送消息到页面的例子,只有hzb这个用户收到</h4>
     80     <label>{{data.hzbtime}}</label> <br/> <br/>
     81 </div>
     82 <div ng-show="data.connected">
     83     <h4>以下是websocket的客户端发消息到服务端,服务端再将该消息返回到客户端(页面)的例子</h4>
     84     <input type="text" ng-model="data.sendMessage" placeholder="请输入内容..." />
     85     <button ng-click="send()" type="button">发送</button>
     86     <br/>
     87     <table>
     88         <thead>
     89         <tr>
     90             <th>消息内容:</th>
     91         </tr>
     92         </thead>
     93         <tbody>
     94         <tr ng-repeat="messageContent in data.receivMessages">
     95             <td>{{messageContent}}</td>
     96         </tr>
     97         </tbody>
     98     </table>
     99 </div>
    100 </body>
    101 </html>
  • 相关阅读:
    C#串口通信程序实现无感知签到与答题
    C# 调用adb command 读取手机型号和IMEI
    sql 截取字符串
    .NET下的ORM框架有哪些
    linq-to-sql实现left join,group by,count
    C# 生成二维码
    数据库面试题.net
    .net面试中的一些常见问题与答案
    Jquery判断其中任意一个文本框的值是否被修改
    矩阵乘法的MPI并行计算
  • 原文地址:https://www.cnblogs.com/fanqisoft/p/11276335.html
Copyright © 2011-2022 走看看