赞
踩
目录
2.2 WebSocket配置类,用于配置WebSocket的相关设置
2.3 自定义WebSocket处理器类,用于处理WebSocket的生命周期事件
2.4 自定义WebSocket握手拦截器,用于增强WebSocket的握手过程
2.5 SessionBean类用于封装与WebSocket会话相关的数据
WebSocket 是一种网络通信协议,用于在单个 TCP 连接上进行全双工通信。它具有实时性、双向通信、低开销和跨域支持等特点,适用于实时聊天、在线游戏等应用场景。在实际应用中,通常与前端技术结合使用,通过 WebSocket API 来实现实时数据的传输和处理。
代码结构
- <properties>
- <java.version>17</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>2.0.32</version>
- </dependency>
- <!-- websocket消息推送 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-websocket</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-tomcat</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- <version>5.8.9</version>
- </dependency>
- <dependency>
- <groupId>org.apache.tomcat.embed</groupId>
- <artifactId>tomcat-embed-websocket</artifactId>
- <version>10.1.20</version>
- </dependency>
-
-
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
- package com.by.config;
-
-
- import jakarta.annotation.Resource;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.socket.config.annotation.EnableWebSocket;
- import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
- import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
-
-
- /**
- * @author 黄远超
- */
- @Configuration
- @EnableWebSocket
- public class MyWsConfig implements WebSocketConfigurer {
- @Resource
- MyWsHandler myWsHandler;
- @Resource
- MyWsInterceptor myWsInterceptor;
- @Override
- public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
- registry.addHandler(myWsHandler,"/myWs1")
- .addInterceptors(myWsInterceptor)
- .setAllowedOrigins("*");
- }
- //访问的位置,设置拦截器,设置拦截范围
- }
- package com.by.config;
-
- import cn.hutool.core.text.StrBuilder;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.boot.web.servlet.server.Session;
- import org.springframework.scheduling.annotation.Scheduled;
- import org.springframework.stereotype.Component;
- import org.springframework.web.socket.CloseStatus;
- import org.springframework.web.socket.TextMessage;
- import org.springframework.web.socket.WebSocketSession;
- import org.springframework.web.socket.handler.AbstractWebSocketHandler;
-
- import java.io.IOException;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.atomic.AtomicInteger;
-
- /**
- 物理程序
- */
- @Component
- @Slf4j
- public class MyWsHandler extends AbstractWebSocketHandler {
- private static Map<String,SessionBean> sessionBeanMap;
- private static AtomicInteger clientIdMaker;
- private static StringBuffer stringBuffer;
- //初始化
- static {
- sessionBeanMap = new ConcurrentHashMap<>();
- clientIdMaker = new AtomicInteger(0);
- stringBuffer = new StringBuffer();
- }
- @Override
- public void afterConnectionEstablished(WebSocketSession session) throws Exception {
- super.afterConnectionEstablished(session);
- SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());
- sessionBeanMap.put(session.getId(),sessionBean);
- log.info(sessionBeanMap.get(session.getId()).getClientId()+"建立连接");
- stringBuffer.append(sessionBeanMap.get(session.getId()).getClientId()+"进入了群聊<br/>");
- sendMessage(sessionBeanMap);
- }
-
- @Override
- protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
- super.handleTextMessage(session, message);
- log.info(sessionBeanMap.get(session.getId()).getClientId()+":"+message.getPayload());
- stringBuffer.append(sessionBeanMap.get(session.getId()).getClientId()+":"+message.getPayload()+"<br/>");
- sendMessage(sessionBeanMap);
- }
- //异常时
- @Override
- public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
- super.handleTransportError(session, exception);
- if (session.isOpen()){
- session.close();
- }
- sessionBeanMap.remove(session.getId());
- }
-
- @Override
- public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
- super.afterConnectionClosed(session, status);
- int clientId = sessionBeanMap.get(session.getId()).getClientId();
- sessionBeanMap.remove(session);
- log.info(clientId+"关闭了连接");
- stringBuffer.append(clientId+"退出了群聊<br/>");
- sendMessage(sessionBeanMap);
- }
-
- public void sendMessage(Map<String,SessionBean> sessionBeanMap){
- for(String key:sessionBeanMap.keySet()){{
- try {
- sessionBeanMap.get(key).getWebSocketSession().sendMessage(new TextMessage(stringBuffer.toString()));
- } catch (IOException e) {
- log.info("出错啦");
- }
- }}
- }
-
- // //定时任务
- // @Scheduled(fixedDelay = 2000)//多少秒执行1次
- // public void sendMessage() throws IOException {
- // for (String key:sessionBeanMap.keySet()){
- // sessionBeanMap.get(key).getWebSocketSession().sendMessage(new TextMessage(":心跳"));
- // }
- // }
- }
- package com.by.config;
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.http.server.ServerHttpRequest;
- import org.springframework.http.server.ServerHttpResponse;
- import org.springframework.stereotype.Component;
- import org.springframework.web.socket.WebSocketHandler;
- import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
-
- import java.util.Map;
-
-
- /**
- * @author 黄远超
- */
- @Component
- @Slf4j
- public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {
- @Override
- public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
- return super.beforeHandshake(request, response, wsHandler, attributes);
- }
-
- @Override
- public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
- super.afterHandshake(request, response, wsHandler, ex);
- }
- }
- package com.by.config;
-
- import jakarta.websocket.Session;
- import lombok.AllArgsConstructor;
- import lombok.Data;
- import org.springframework.web.server.WebSession;
- import org.springframework.web.socket.WebSocketSession;
-
-
- /**
- * @author 黄远超
- */
- /**
- * SessionBean类用于封装与WebSocket会话相关的数据。
- * webSocketSession 代表一个WebSocket会话的对象,用于与客户端进行双向通信。
- * clientId 客户端的唯一标识符,用于区分不同的客户端连接。
- */
- @Data
- @AllArgsConstructor
- public class SessionBean {
- private WebSocketSession webSocketSession; // WebSocket会话对象
- private Integer clientId; // 客户端ID
- }
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <p style="border: 1px solid black;width: 400px;height: 600px" id="talkMsg"></p>
- <input id="message" />
- <button id="sendBtn" onclick="sendMsg()">发送</button>
- </body>
- <script>
- let ws = new WebSocket("ws://localhost:8080/myWs1")
- ws.onopen=function (){
- }
- ws.onmessage=function (message) {
- document.getElementById("talkMsg").innerHTML = message.data
- }
- function sendMsg() {
- ws.send(document.getElementById("message").value)
- document.getElementById("message").value=""
- }
- </script>
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。