当前位置:   article > 正文

SpringBoot 结合 WebSocket 实现聊天功能_springboot websocket

springboot websocket

目录

一、WebSocket  介绍

二、源码

2.1 pom.xml

2.2 WebSocket配置类,用于配置WebSocket的相关设置

 2.3 自定义WebSocket处理器类,用于处理WebSocket的生命周期事件

2.4 自定义WebSocket握手拦截器,用于增强WebSocket的握手过程

 2.5 SessionBean类用于封装与WebSocket会话相关的数据

2.6 前端代码

三、界面效果


一、WebSocket  介绍

WebSocket 是一种网络通信协议,用于在单个 TCP 连接上进行全双工通信。它具有实时性、双向通信、低开销和跨域支持等特点,适用于实时聊天、在线游戏等应用场景。在实际应用中,通常与前端技术结合使用,通过 WebSocket API 来实现实时数据的传输和处理。

二、源码

代码结构

2.1 pom.xml

  1. <properties>
  2. <java.version>17</java.version>
  3. </properties>
  4. <dependencies>
  5. <dependency>
  6. <groupId>com.alibaba</groupId>
  7. <artifactId>fastjson</artifactId>
  8. <version>2.0.32</version>
  9. </dependency>
  10. <!-- websocket消息推送 -->
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-websocket</artifactId>
  14. <exclusions>
  15. <exclusion>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter-tomcat</artifactId>
  18. </exclusion>
  19. </exclusions>
  20. </dependency>
  21. <dependency>
  22. <groupId>cn.hutool</groupId>
  23. <artifactId>hutool-all</artifactId>
  24. <version>5.8.9</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.apache.tomcat.embed</groupId>
  28. <artifactId>tomcat-embed-websocket</artifactId>
  29. <version>10.1.20</version>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework.boot</groupId>
  33. <artifactId>spring-boot-starter-web</artifactId>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.projectlombok</groupId>
  37. <artifactId>lombok</artifactId>
  38. <optional>true</optional>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-starter-test</artifactId>
  43. <scope>test</scope>
  44. </dependency>
  45. </dependencies>
  46. <build>
  47. <plugins>
  48. <plugin>
  49. <groupId>org.springframework.boot</groupId>
  50. <artifactId>spring-boot-maven-plugin</artifactId>
  51. <configuration>
  52. <excludes>
  53. <exclude>
  54. <groupId>org.projectlombok</groupId>
  55. <artifactId>lombok</artifactId>
  56. </exclude>
  57. </excludes>
  58. </configuration>
  59. </plugin>
  60. </plugins>
  61. </build>

2.2 WebSocket配置类,用于配置WebSocket的相关设置

  1. package com.by.config;
  2. import jakarta.annotation.Resource;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.socket.config.annotation.EnableWebSocket;
  5. import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
  6. import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
  7. /**
  8. * @author 黄远超
  9. */
  10. @Configuration
  11. @EnableWebSocket
  12. public class MyWsConfig implements WebSocketConfigurer {
  13. @Resource
  14. MyWsHandler myWsHandler;
  15. @Resource
  16. MyWsInterceptor myWsInterceptor;
  17. @Override
  18. public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
  19. registry.addHandler(myWsHandler,"/myWs1")
  20. .addInterceptors(myWsInterceptor)
  21. .setAllowedOrigins("*");
  22. }
  23. //访问的位置,设置拦截器,设置拦截范围
  24. }

 2.3 自定义WebSocket处理器类,用于处理WebSocket的生命周期事件

  1. package com.by.config;
  2. import cn.hutool.core.text.StrBuilder;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.boot.web.servlet.server.Session;
  5. import org.springframework.scheduling.annotation.Scheduled;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.socket.CloseStatus;
  8. import org.springframework.web.socket.TextMessage;
  9. import org.springframework.web.socket.WebSocketSession;
  10. import org.springframework.web.socket.handler.AbstractWebSocketHandler;
  11. import java.io.IOException;
  12. import java.util.Map;
  13. import java.util.concurrent.ConcurrentHashMap;
  14. import java.util.concurrent.atomic.AtomicInteger;
  15. /**
  16. 物理程序
  17. */
  18. @Component
  19. @Slf4j
  20. public class MyWsHandler extends AbstractWebSocketHandler {
  21. private static Map<String,SessionBean> sessionBeanMap;
  22. private static AtomicInteger clientIdMaker;
  23. private static StringBuffer stringBuffer;
  24. //初始化
  25. static {
  26. sessionBeanMap = new ConcurrentHashMap<>();
  27. clientIdMaker = new AtomicInteger(0);
  28. stringBuffer = new StringBuffer();
  29. }
  30. @Override
  31. public void afterConnectionEstablished(WebSocketSession session) throws Exception {
  32. super.afterConnectionEstablished(session);
  33. SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());
  34. sessionBeanMap.put(session.getId(),sessionBean);
  35. log.info(sessionBeanMap.get(session.getId()).getClientId()+"建立连接");
  36. stringBuffer.append(sessionBeanMap.get(session.getId()).getClientId()+"进入了群聊<br/>");
  37. sendMessage(sessionBeanMap);
  38. }
  39. @Override
  40. protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
  41. super.handleTextMessage(session, message);
  42. log.info(sessionBeanMap.get(session.getId()).getClientId()+":"+message.getPayload());
  43. stringBuffer.append(sessionBeanMap.get(session.getId()).getClientId()+":"+message.getPayload()+"<br/>");
  44. sendMessage(sessionBeanMap);
  45. }
  46. //异常时
  47. @Override
  48. public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
  49. super.handleTransportError(session, exception);
  50. if (session.isOpen()){
  51. session.close();
  52. }
  53. sessionBeanMap.remove(session.getId());
  54. }
  55. @Override
  56. public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
  57. super.afterConnectionClosed(session, status);
  58. int clientId = sessionBeanMap.get(session.getId()).getClientId();
  59. sessionBeanMap.remove(session);
  60. log.info(clientId+"关闭了连接");
  61. stringBuffer.append(clientId+"退出了群聊<br/>");
  62. sendMessage(sessionBeanMap);
  63. }
  64. public void sendMessage(Map<String,SessionBean> sessionBeanMap){
  65. for(String key:sessionBeanMap.keySet()){{
  66. try {
  67. sessionBeanMap.get(key).getWebSocketSession().sendMessage(new TextMessage(stringBuffer.toString()));
  68. } catch (IOException e) {
  69. log.info("出错啦");
  70. }
  71. }}
  72. }
  73. // //定时任务
  74. // @Scheduled(fixedDelay = 2000)//多少秒执行1次
  75. // public void sendMessage() throws IOException {
  76. // for (String key:sessionBeanMap.keySet()){
  77. // sessionBeanMap.get(key).getWebSocketSession().sendMessage(new TextMessage(":心跳"));
  78. // }
  79. // }
  80. }

2.4 自定义WebSocket握手拦截器,用于增强WebSocket的握手过程

  1. package com.by.config;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.http.server.ServerHttpRequest;
  4. import org.springframework.http.server.ServerHttpResponse;
  5. import org.springframework.stereotype.Component;
  6. import org.springframework.web.socket.WebSocketHandler;
  7. import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
  8. import java.util.Map;
  9. /**
  10. * @author 黄远超
  11. */
  12. @Component
  13. @Slf4j
  14. public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {
  15. @Override
  16. public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
  17. return super.beforeHandshake(request, response, wsHandler, attributes);
  18. }
  19. @Override
  20. public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
  21. super.afterHandshake(request, response, wsHandler, ex);
  22. }
  23. }

 2.5 SessionBean类用于封装与WebSocket会话相关的数据

  1. package com.by.config;
  2. import jakarta.websocket.Session;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5. import org.springframework.web.server.WebSession;
  6. import org.springframework.web.socket.WebSocketSession;
  7. /**
  8. * @author 黄远超
  9. */
  10. /**
  11. * SessionBean类用于封装与WebSocket会话相关的数据。
  12. * webSocketSession 代表一个WebSocket会话的对象,用于与客户端进行双向通信。
  13. * clientId 客户端的唯一标识符,用于区分不同的客户端连接。
  14. */
  15. @Data
  16. @AllArgsConstructor
  17. public class SessionBean {
  18. private WebSocketSession webSocketSession; // WebSocket会话对象
  19. private Integer clientId; // 客户端ID
  20. }

2.6 前端代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <p style="border: 1px solid black;width: 400px;height: 600px" id="talkMsg"></p>
  9. <input id="message" />
  10. <button id="sendBtn" onclick="sendMsg()">发送</button>
  11. </body>
  12. <script>
  13. let ws = new WebSocket("ws://localhost:8080/myWs1")
  14. ws.onopen=function (){
  15. }
  16. ws.onmessage=function (message) {
  17. document.getElementById("talkMsg").innerHTML = message.data
  18. }
  19. function sendMsg() {
  20. ws.send(document.getElementById("message").value)
  21. document.getElementById("message").value=""
  22. }
  23. </script>
  24. </html>

三、界面效果

访问 http://localhost:8080/Chat.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/679882
推荐阅读
相关标签
  

闽ICP备14008679号