Javaweb使用websocket
先看结构及效果
MyWebSocketHandler用于处理消息
package com.cili.learning.springbootwebsocket.websockethandler;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
/**
* @author 码头薯条Pro
* @date 2025/7/14 23:30
* <p></p>
* <p>
* 视频讲解链接:
* <p>
* 题解链接:
* <p>
* 题目链接:
*/@Slf4j
public class MyWebSocketHandler extends TextWebSocketHandler {
// 用于保存所有连接的会话
private static final Set<WebSocketSession> sessions = Collections.synchronizedSet(new HashSet<>());
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String query = Objects.requireNonNull(session.getUri()).getQuery();
Map<String, String> paramMap = splitQuery(query);
String bondTypeListStr = paramMap.get("bondTypeList");
if (StringUtils.isNotBlank(bondTypeListStr)) {
ArrayList<String> bondTypeList = new ArrayList<>(Arrays.asList(bondTypeListStr.split(",")));
session.getAttributes().put("bondTypeList", bondTypeList);
}
sessions.add(session);
}
private Map<String, String> splitQuery(String query) throws UnsupportedEncodingException {
Map<String, String> query_pairs = new LinkedHashMap<>();
if (query == null) return query_pairs;
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
query_pairs.put(
URLDecoder.decode(pair.substring(0, idx), "UTF-8"),
URLDecoder.decode(pair.substring(idx + 1), "UTF-8")
);
}
return query_pairs;
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
log.info("WEBSOCKET连接关闭了!");
sessions.remove(session);
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
if (StringUtils.isNotBlank(payload)) {
Map params = new ObjectMapper().readValue(payload, Map.class);
if (null != params && null != params.get("bondTypeList")) {
session.getAttributes().put("bondTypeList", params.get("bondTypeList"));
// session.sendMessage(new TextMessage("查询债券品种条件改为: " + params.get("bondTypeList")));
}
try {
MyWebSocketHandler.sendMessageToAll("查询债券品种条件改为: " + params.get("bondTypeList"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 服务器主动推送方法
public static void sendMessageToAll(String message) throws Exception {
synchronized (sessions) {
for (WebSocketSession session : sessions) {
if (session.isOpen()) {
Object conditionObj = session.getAttributes().get("bondTypeList");
List<String> bondTypeList = new ArrayList<>();
if (conditionObj instanceof List) {
bondTypeList = (List<String>) conditionObj;
log.info("过滤条件是:{}", JSON.toJSONString(bondTypeList));
}
session.sendMessage(new TextMessage(message + JSON.toJSONString(bondTypeList)));
}
}
}
}
}
WebSocketConfig用于配置建联地址等
package com.cili.learning.springbootwebsocket.config;
import com.cili.learning.springbootwebsocket.interceptor.MyWebSocketInterceptor;
import com.cili.learning.springbootwebsocket.websockethandler.MyWebSocketHandler;
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 码头薯条Pro
* @date 2025/7/14 23:35
* <p></p>
* <p>
* 视频讲解链接:
* <p>
* 题解链接:
* <p>
* 题目链接:
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/ws/test")
.addInterceptors(new MyWebSocketInterceptor())
.setAllowedOrigins("*");
}
}
SchedulerConfig必须配置这个
package com.cili.learning.springbootwebsocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
* @author 码头薯条Pro
* @date 2025/7/14 23:37
* <p></p>
* <p>
* 视频讲解链接:
* <p>
* 题解链接:
* <p>
* 题目链接:
*/
@Configuration
public class SchedulerConfig {
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5);
scheduler.setThreadNamePrefix("ws-sockjs-task-");
scheduler.setRemoveOnCancelPolicy(true);
return scheduler;
}
}
MyWebSocketInterceptor建联的拦截器
package com.cili.learning.springbootwebsocket.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* @author 码头薯条Pro
* @date 2025/7/14 23:36
* <p></p>
* <p>
* 视频讲解链接:
* <p>
* 题解链接:
* <p>
* 题目链接:
*/
@Slf4j
public class MyWebSocketInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler wsHandler, Map<String, Object> attributes) {
if (request instanceof ServletServerHttpRequest) {
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
String token = servletRequest.getHeader("User-Token");
log.info("收到header token:" + token);
// 放进attributes方便handler获取
if (null != token) {
attributes.put("token", token);
}
}
return true; // 允许握手
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler wsHandler, Exception exception) {
}
}
SpringBootWebsocketApplication启动类
package com.cili.learning.springbootwebsocket;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author 码头薯条Pro
* @date 2025/7/14 23:17
* <p></p>
* <p>
* 视频讲解链接:
* <p>
* 题解链接:
* <p>
* 题目链接:
*/
@EnableScheduling
@SpringBootApplication
public class SpringBootWebsocketApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebsocketApplication.class, args);
}
}
POM依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<groupId>com.cili.learn</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-websocket</name>
<description>springboot-websocket</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.14</version> <!-- 建议使用最新稳定版 -->
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
</dependency>
</dependencies>
<!-- <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>-->
</project>
展示效果
源码
https://gitee.com/coder-msc/cili-springboot-learning/tree/master/spring-boot-websocket