Eclipse 搭建一个简单的SpringBoot+WebSocket环境

WebSocket是一种在单个TCP连接上进行全双工通信的协议。

WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。

WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

使用SpringBoot+WebSocket搭建一个多人聊天系统

1、新建Spring Starter Project

 

 

 

 

 

 2、添加对WebSocket的支持

 注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。

 1 package com.zzq.config;
 2 
 3 import org.springframework.context.annotation.Bean;
 4 import org.springframework.context.annotation.Configuration;
 5 import org.springframework.web.socket.server.standard.ServerEndpointExporter;
 6 
 7 /**
 8  * 
 9  * @author ZZQ-PC
10  *
11  */
12 @Configuration
13 public class AppConfiguration {
14 
15     @Bean
16     public ServerEndpointExporter serverEndpointExporter(){
17         return new ServerEndpointExporter();
18     }
19     
20 }

 3、创建WebSocket的实现类

@ServerEndpoint("/webSocket/{page}")中的值就是需要访问的地址,和Controller中的@RequestMapping有点类似。然后实现@OnOpen(打开连接),@OnClose(关闭连接),@onMessage(收到消息),@Error(触发异常)。

 

 1 package com.zzq.config;
 2 
 3 import java.io.IOException;
 4 import java.util.Map;
 5 import java.util.Set;
 6 import java.util.concurrent.ConcurrentHashMap;
 7 import java.util.concurrent.CopyOnWriteArraySet;
 8 import java.util.concurrent.atomic.AtomicInteger;
 9 
10 import javax.websocket.OnClose;
11 import javax.websocket.OnError;
12 import javax.websocket.OnMessage;
13 import javax.websocket.OnOpen;
14 import javax.websocket.Session;
15 import javax.websocket.server.PathParam;
16 import javax.websocket.server.ServerEndpoint;
17 
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20 import org.springframework.stereotype.Component;
21 
22 /**
23  * 
24  * @author ZZQ-PC
25  *
26  */
27 @Component
28 @ServerEndpoint("/webSocket/{page}")
29 public class WebSocket {
30     private Logger log = LoggerFactory.getLogger(this.getClass());
31     
32     /**
33      * 用来记录房间的人数
34      */
35     private static AtomicInteger onlinePersons = new AtomicInteger(0);
36 
37     /**
38      * 用来记录房间及人数
39      */
40     private static Map<String,Set> roomMap = new ConcurrentHashMap(8);
41 
42     @OnOpen
43     public void open(@PathParam("page") String page, Session session) throws IOException {
44         Set set = roomMap.get(page);
45         // 如果是新的房间,则创建一个映射,如果房间已存在,则把用户放进去
46         if(set == null){
47             set = new CopyOnWriteArraySet();
48             set.add(session);
49             roomMap.put(page,set);
50         }else{
51             set.add(session);
52         }
53         // 房间人数+1
54         onlinePersons.incrementAndGet();
55         log.info("新用户{}进入聊天,房间人数:{}",session.getId(),onlinePersons);
56     }
57 
58     @OnClose
59     public void close(@PathParam("page") String page, Session session){
60         // 如果某个用户离开了,就移除相应的信息
61         if(roomMap.containsKey(page)){
62             roomMap.get(page).remove(session);
63         }
64         // 房间人数-1
65         onlinePersons.decrementAndGet();
66         log.info("用户{}退出聊天,房间人数:{}",session.getId(),onlinePersons);
67     }
68 
69     @OnMessage
70     public void reveiveMessage(@PathParam("page") String page, Session session,String message) throws IOException {
71         log.info("接受到用户{}的数据:{}",session.getId(),message);
72         // 拼接一下用户信息
73         String msg = session.getId()+" : "+ message;
74         Set<Session> sessions = roomMap.get(page);
75         // 给房间内所有用户推送信息
76         for(Session s : sessions){
77             s.getBasicRemote().sendText(msg);
78         }
79     }
80 
81     @OnError
82     public void error(Throwable throwable){
83         try {
84             throw throwable;
85         } catch (Throwable e) {
86             log.error("未知错误");
87         }
88     }
89 }

4、在src/main/resources/static文件夹下新建index.html。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="UTF-8"></meta>
 5 <title>springboot项目WebSocket测试demo</title>
 6 </head>
 7 <body>
 8     <h3>springboot项目websocket测试demo</h3>
 9     <h4>测试说明</h4>
10     <h5>文本框中数据数据,点击‘发送测试’,文本框中的数据会发送到后台websocket,后台接受到之后,会再推送数据到前端,展示在下方;点击关闭连接,可以关闭该websocket;可以跟踪代码,了解具体的流程;代码上有详细注解</h5>
11     <br />
12     <input id="text" type="text" />
13     <button onclick="send()">发送测试</button>
14     <hr />
15     <button onclick="clos()">关闭连接</button>
16     <hr />
17     <div id="message"></div>
18     <script>
19     var websocket = null;
20     if('WebSocket' in window){
21         websocket = new WebSocket("ws://127.0.0.1:8080/webSocket/1");
22     }else{
23         alert("您的浏览器不支持websocket");
24     }
25     websocket.onerror = function(){
26         setMessageInHtml("send error!");
27     }
28     websocket.onopen = function(){
29         setMessageInHtml("连接成功!")
30         setTimeout(function(){setMessageInHtml("欢迎来到这里!")
31     },2000)
32     }
33     websocket.onmessage = e => setMessageInHtml(e.data)
34     websocket.onclose = function(){
35         setMessageInHtml("连接断开!")
36     }
37     window.onbeforeunload = function(){
38         clos();
39     }
40     function setMessageInHtml(message){
41         document.getElementById('message').innerHTML += message+"</br>";
42     }
43     function clos(){
44         websocket.close(3000,"强制关闭");
45     }
46     function send(){
47         var msg = document.getElementById('text').value;
48         websocket.send(msg);
49     }
50 </script>
51 </body>
52 </html>

 5、启动Spring boot工程

 

 

 

 

至此,一个简单的SpringBoot+WebSocket项目搭建完毕。

 

posted @ 2021-07-30 16:56  ZZQJWJ  阅读(339)  评论(0编辑  收藏  举报