首先,在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和浏览器中已经打印了发送的消息字样了
上图是客户端访问的浏览器所显示的消息,下图是服务器端所打印的消息
好了,实现的很成功,接下来就是对发送的数据进行替换就差不多了,哈哈~