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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM