springboot1.5.9  實現websocket

首先,在springboot項目創建並配置成功的基礎上對websocket進行整合。

1、在pom文件中添加對websocket的依賴

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

2、個人習慣是先從後端寫到前端,先寫websocket的配置類吧

  1 import org.springframework.stereotype.Component;
  2 
  3 import javax.websocket.*;
  4 import javax.websocket.server.ServerEndpoint;
  5 import java.io.IOException;
  6 import java.util.concurrent.CopyOnWriteArraySet;
  7 
  8 /**
  9 * @Name:WebSocket
 10 * @Description:WebSocket配置
 11 * @Version:V1.0.0
 12 * @Author:mYunYu
 13 * @Create Date:2018/11/15 14:45
 14 */
 15 @Component
 16 @ServerEndpoint(value = "/ws/webSocket" , encoders = {EncoderClassVo.class})
 17 public class WebSocket {
 18     //每個客戶端都會有相應的session,服務端可以發送相關消息
 19     private Session session;
 20 
 21     //J.U.C包下線程安全的類,主要用來存放每個客戶端對應的webSocket連接
 22     private static CopyOnWriteArraySet<WebSocket> copyOnWriteArraySet = new CopyOnWriteArraySet<WebSocket>();
 23 
 24    /**
 25    * @Name:onOpen
 26    * @Description:打開連接。進入頁面後會自動發請求到此進行連接
 27    * @Author:mYunYu
 28    * @Create Date:14:46 2018/11/15
 29    * @Parameters:
 30    * @Return:
 31    */
 32     @OnOpen
 33     public void onOpen(Session session) {
 34         this.session = session;
 35         copyOnWriteArraySet.add(this);
 36         System.out.println("websocket有新的連接, 總數:"+ copyOnWriteArraySet.size());
 37 
 38     }
 39 
 40    /**
 41    * @Name:onClose
 42    * @Description:用戶關閉頁面,即關閉連接
 43    * @Author:mYunYu
 44    * @Create Date:14:46 2018/11/15
 45    * @Parameters:
 46    * @Return:
 47    */
 48     @OnClose
 49     public void onClose() {
 50         copyOnWriteArraySet.remove(this);
 51         System.out.println("websocket連接斷開, 總數:"+ copyOnWriteArraySet.size());
 52     }
 53 
 54     /**
 55     * @Name:onMessage
 56     * @Description:測試客戶端發送消息,測試是否聯通
 57     * @Author:mYunYu
 58     * @Create Date:14:46 2018/11/15
 59     * @Parameters:
 60     * @Return:
 61     */
 62     @OnMessage
 63     public void onMessage(String message) {
 64         System.out.println("websocket收到客戶端發來的消息:"+message);
 65     }
 66 
 67     /**
 68     * @Name:onError
 69     * @Description:出現錯誤
 70     * @Author:mYunYu
 71     * @Create Date:14:46 2018/11/15
 72     * @Parameters:
 73     * @Return:
 74     */
 75     @OnError
 76     public void onError(Session session, Throwable error) {
 77         System.out.println("發生錯誤:" + error.getMessage() + "; sessionId:" + session.getId());
 78         error.printStackTrace();
 79     }
 80 
 81     public void sendMessage(Object object){
 82         //遍歷客戶端
 83         for (WebSocket webSocket : copyOnWriteArraySet) {
 84             System.out.println("websocket廣播消息:" + object.toString());
 85             try {
 86                 //服務器主動推送
 87                 webSocket.session.getBasicRemote().sendObject(object) ;
 88             } catch (Exception e) {
 89                 e.printStackTrace();
 90             }
 91         }
 92     }
 93 
 94     /**
 95     * @Name:sendMessage
 96     * @Description:用於發送給客戶端消息(羣發)
 97     * @Author:mYunYu
 98     * @Create Date:14:46 2018/11/15
 99     * @Parameters:
100     * @Return:
101     */
102     public void sendMessage(String message) {
103         //遍歷客戶端
104         for (WebSocket webSocket : copyOnWriteArraySet) {
105             System.out.println("websocket廣播消息:" + message);
106             try {
107                 //服務器主動推送
108                 webSocket.session.getBasicRemote().sendText(message);
109             } catch (Exception e) {
110                 e.printStackTrace();
111             }
112         }
113     }
114 
115     /**
116     * @Name:sendMessage
117     * @Description:用於發送給指定客戶端消息
118     * @Author:mYunYu
119     * @Create Date:14:47 2018/11/15
120     * @Parameters:
121     * @Return:
122     */
123     public void sendMessage(String sessionId, String message) throws IOException {
124         Session session = null;
125         WebSocket tempWebSocket = null;
126         for (WebSocket webSocket : copyOnWriteArraySet) {
127             if (webSocket.session.getId().equals(sessionId)) {
128                 tempWebSocket = webSocket;
129                 session = webSocket.session;
130                 break;
131             }
132         }
133         if (session != null) {
134             tempWebSocket.session.getBasicRemote().sendText(message);
135         } else {
136             System.out.println("沒有找到你指定ID的會話:{}"+ "; sessionId:" + sessionId);
137         }
138     }
139 
140     /**
141      * 如果使用springboot內置tomcat,需要配置,否則不需要
142      *
143      * @return
144      */
145 //    @Bean
146 //    public ServerEndpointExporter serverEndpointExporter() {
147 //        return new ServerEndpointExporter();
148 //    }
149 
150 
151 }

上面類中的紅色註釋的代碼是隻有當springboot項目使用內置tomcat時需要配置(即打成jar包),如果使用外置tomcat則不需要配置(即打成war包)

3、配置編碼器,主要是需要後端向前端發送對象數據,如果只是發送普通的字符串數據的話,就不需要

 1 import com.alibaba.fastjson.JSON;
 2 import com.xxx.utils.MsgUtil;
 3 
 4 import javax.websocket.EncodeException;
 5 import javax.websocket.Encoder;
 6 import javax.websocket.EndpointConfig;
 7 
 8 /**
 9 * @Name:EncoderClassVo
10 * @Description:編碼器,防止發送對象出錯
11 * @Version:V1.0.0
12 * @Author:mYunYu
13 * @Create Date:2018/11/15 14:43
14 */
15 public class EncoderClassVo implements Encoder.Text<MsgUtil> {
16 
17     @Override
18     public void init(EndpointConfig endpointConfig) {
19 
20     }
21 
22     @Override
23     public void destroy() {
24 
25     }
26 
27     @Override
28     public String encode(MsgUtil msgUtil) throws EncodeException {
29         try{
30             return JSON.toJSONString(msgUtil) ;
31         }catch (Exception e){
32             e.printStackTrace() ;
33             return null;
34         }
35     }
36 }

4、接下來就是寫controller層了,我這邊demo只是簡單的發送一些隨機的數據,具體信息還需要根據各個項目需要來寫

 1 import com.xxx.pojo.User;
 2 import com.xxx.utils.MsgUtil;
 3 import com.xxx.webSocket.WebSocket;
 4 import org.springframework.web.bind.annotation.RequestMapping;
 5 import org.springframework.web.bind.annotation.RestController;
 6 
 7 import javax.annotation.Resource;
 8 import java.io.IOException;
 9 
10 /**
11 * @Name:SocketController
12 * @Description:消息發送Controller
13 * @Version:V1.0.0
14 * @Author:mYunYu
15 * @Create Date:2018/11/15 16:44
16 */
17 @RestController
18 public class SocketController {
19 
20     @Resource
21     WebSocket webSocket;
22 
23     /**
24     * @Name:helloManyWebSocket
25     * @Description:羣發消息
26     * @Author:mYunYu
27     * @Create Date:16:44 2018/11/15
28     * @Parameters:
29     * @Return:
30     */
31     @RequestMapping("many")
32     public String helloManyWebSocket(){
33 
34         int i = 1 ;
35         while(i > 0){
36             i=1+(int)(Math.random()*600) ;
37             User user = new User() ;
38             user.setUserid(i+1) ;
39             user.setUsername(String.valueOf(i) + String.valueOf(i+i)) ;
40 
41             //將對象轉爲json對象,併發送到前端
42             MsgUtil msgUtil = MsgUtil.success().addMsg("map", user);
43             webSocket.sendMessage(msgUtil);
44 
45             try{
46                 Thread.sleep(1000) ;
47             }catch (Exception e){
48                 e.printStackTrace() ;
49             }
50         }
51 
52         return "發送成功";
53     }
54 
55     /**
56     * @Name:helloOneWebSocket
57     * @Description:根據session單個發送消息
58     * @Author:mYunYu
59     * @Create Date:16:44 2018/11/15
60     * @Parameters:
61     * @Return:
62     */
63     @RequestMapping("one")
64     public String helloOneWebSocket(String sessionId) throws IOException {
65         //向某個人發送消息
66         webSocket.sendMessage(sessionId,"你好~!,單個用戶");
67 
68         return "發送成功";
69     }
70 
71 
72 }

5、接下來該在前端寫配置了,我這裏使用的是thymeleaf模板

 1 <!DOCTYPE html >
 2 <html lang="en" xmlns:th="http://www.thymeleaf.org">
 3 <head>
 4     <meta charset="UTF-8"/>
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 自動連接websocket
10 <script type="text/javascript">
11 
12     var socket;
13     if (typeof (WebSocket) == "undefined") {
14         console.log("遺憾:您的瀏覽器不支持WebSocket");
15     } else {
16         console.log("恭喜:您的瀏覽器支持WebSocket");
17 
18         //實現化WebSocket對象
19         //指定要連接的服務器地址與端口建立連接
20         //注意ws、wss使用不同的端口。我使用自簽名的證書測試,
21         //無法使用wss,瀏覽器打開WebSocket時報錯
22         //ws對應http、wss對應https。
23         socket = new WebSocket("ws://127.0.0.1:端口號/項目名/ws/webSocket");
24         //連接打開事件
25         socket.onopen = function() {
26             console.log("Socket 已打開");
27             socket.send("消息發送測試(From Client)");
28         };
29         //收到消息事件
30         socket.onmessage = function(msg) {
31             console.log(msg.data) ;
32         };
33         //連接關閉事件
34         socket.onclose = function() {
35             console.log("Socket已關閉");
36         };
37         //發生了錯誤事件
38         socket.onerror = function() {
39             alert("Socket發生了錯誤");
40         }
41 
42         //窗口關閉時,關閉連接
43         window.unload=function() {
44             socket.close();
45         };
46 
47     }
48 
49 </script>
50 
51 
52 </body>
53 </html>

6、最後就是測試了,先右擊項目,選擇Run Mavan-->clear install進行項目打包

打包成功之後再啓動外置tomcat來啓動項目

啓動項目成功,在瀏覽器中訪問

按f12,如果出現”Socket已打開“字樣,則表示客戶端連接ok,現在需要使用服務端向客戶端發送消息

再打開另一個瀏覽器,輸入http://localhost:端口號/項目名/many進行訪問,就可以觀察到idea和瀏覽器中已經打印了發送的消息字樣了

上圖是客戶端訪問的瀏覽器所顯示的消息,下圖是服務器端所打印的消息

好了,實現的很成功,接下來就是對發送的數據進行替換就差不多了,哈哈~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章