springboot1.5.9整合websocket实现实时显示的小demo

最近由于项目需要实时显示数据库更新的数据变化情况,一开始想过在前端使用ajax异步轮询方法实现,但后面考虑到性能和流量等要求,就放弃该方法而选择使用websocket(毕竟现在springboot整合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和浏览器中已经打印了发送的消息字样了

上图是客户端访问的浏览器所显示的消息,下图是服务器端所打印的消息

好了,实现的很成功,接下来就是对发送的数据进行替换就差不多了,哈哈~

转载于:https://www.cnblogs.com/mYunYu/p/9964673.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值