一、在项目中pom文件引入websocket相关依赖
<!-- spring websocket -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-websocket</artifactid>
</dependency>
二、创建websocketinterceptor类
创建websocketinterceptor类,实现handshakeinterceptor接口。
import org.springframework.http.server.serverhttprequest;
import org.springframework.http.server.serverhttpresponse;
import org.springframework.web.socket.websockethandler;
import org.springframework.web.socket.server.handshakeinterceptor;
import java.util.map;
public class websocketinterceptor implements handshakeinterceptor {
@override
public boolean beforehandshake(serverhttprequest request, serverhttpresponse response,
websockethandler wshandler, map<string, object> attributes) throws exception {
// 从请求中获取查询参数并存入attributes中
string querystring = request.geturi().getquery();
if (querystring != null) {
string[] queryparams = querystring.split("&");
for (string queryparam : queryparams) {
string[] keyvalue = queryparam.split("=");
if (keyvalue.length == 2) {
attributes.put(keyvalue[0], keyvalue[1]);
}
}
}
return true;
}
@override
public void afterhandshake(serverhttprequest request, serverhttpresponse response,
websockethandler wshandler, exception ex) {
// 握手完成后不需要执行任何操作
}
}
三、创建websocketconfig类
创建websocketconfig类,实现websocketconfigurer接口,注意加入相关注解,否则springboot启动后websocket无法自动运行
@slf4j
@configuration
@enablewebsocket
public class websocketconfig implements websocketconfigurer {
@override
public void registerwebsockethandlers(websockethandlerregistry registry) {
registry.addhandler(mywebsockethandler(), "/websocket").setallowedorigins("*")
.addinterceptors(new websocketinterceptor());
}
@bean
public mywebsockethandler mywebsockethandler() {
return new mywebsockethandler();
}
}
四、创建mywebsockethandler类,实textwebsockethandler接口
import cn.hutool.crypto.digest.digestutil;
import com.manage.component.socket.entity.keyservermessage;
import com.manage.component.security.util.jsonutil;
import lombok.extern.slf4j.slf4j;
import org.springframework.messaging.handler.annotation.messagemapping;
import org.springframework.messaging.handler.annotation.payload;
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.ioexception;
import java.nio.charset.standardcharsets;
import java.nio.charset.unsupportedcharsetexception;
import java.util.list;
import java.util.map;
import java.util.concurrent.copyonwritearraylist;
@slf4j
public class mywebsockethandler extends textwebsockethandler {
// 存储连接的客户端 session
private static list<websocketsession> sessions = new copyonwritearraylist<>(); // 使用并发安全的 list 实现
public static list<websocketsession> getsessions() {
return sessions;
}
@override
public void afterconnectionestablished(websocketsession session) throws exception {
// 获取握手请求中传递的查询参数
map<string, object> attributes = session.getattributes();
string type = (string) attributes.get("type");
string devinfo = (string) attributes.get("devinfo");
// 在这里处理连接建立后的逻辑,可以使用type和devinfo参数
system.out.println("websocket opened with type: " + type + " and devinfo: " + devinfo);
}
@override
protected void handletextmessage(websocketsession session, textmessage message) throws ioexception {
// 接收到客户端消息时的处理逻辑
try {
string messagetext = new string(message.asbytes(), standardcharsets.utf_8);
log.info("接收到客户端消息:" + messagetext);
} catch (unsupportedcharsetexception e) {
log.error("解析消息时发生异常", e);
}
}
@override
public void afterconnectionclosed(websocketsession session, closestatus status) {
sessions.remove(session);
log.info("websocket 连接已关闭。关闭状态:" + status);
}
// 后台数据发生变化时,通过 websocket 推送数据给客户端
public void pushdatatoclients(string data) throws ioexception {
for (websocketsession session : sessions) {
session.sendmessage(new textmessage(data.getbytes(standardcharsets.utf_8))); // 指定字符编码为utf-8
}
}
// 关闭指定客户端的连接
public void closeconnection(websocketsession session) {
sessions.remove(session);
try {
session.close(); // 主动关闭websocket连接
} catch (ioexception e) {
e.printstacktrace();
}
}
@messagemapping("/app/message") // 定义与客户端发送消息时的目标端点匹配的映射路径
public void handlemessage(@payload string message) {
// 在这里处理接收到的消息
log.warn("received message from client: " + message);
}
}
在上面服务连接中传递了两个参数:type 和 devinfo ,并正常接收,启动springboot,websocket服务自动启动,因为加了注解,无需在启动类中调用。
服务地址为: ws://127.0.0.1:4046/websocket?type=1&devinfo=bbbb ,其中 type的值和devinfo的值可以任意传递,接收成功
2024-05-09 10:11:30 [http-nio-4046-exec-3] debug org.springframework.security.web.filterchainproxy -/websocket?type=1&devinfo=bbbb has an empty filter list
2024-05-09 10:11:30 [http-nio-4046-exec-3] debug org.springframework.web.servlet.dispatcherservlet -get "/websocket?type=1&devinfo=bbbb", parameters={masked}
2024-05-09 10:11:30 [http-nio-4046-exec-3] debug org.springframework.web.socket.server.support.websockethandlermapping -mapped to org.springframework.web.socket.server.support.websockethttprequesthandler@6a51ae7c
2024-05-09 10:11:30 [http-nio-4046-exec-3] debug org.springframework.web.socket.server.support.websockethttprequesthandler -get /websocket
2024-05-09 10:11:30 [http-nio-4046-exec-3] debug org.springframework.web.servlet.dispatcherservlet -completed 101 switching_protocols
2024-05-09 10:11:30 [http-nio-4046-exec-3] debug org.springframework.web.socket.handler.loggingwebsockethandlerdecorator -new standardwebsocketsession[id=ddaf2ce8-ca6b-45f5-a540-68b7dd70819a, uri=ws://127.0.0.1:4046/websocket?type=1&devinfo=bbbb]
websocket opened with type: 1 and devinfo: bbbb
启动并完美接收,成功!
发表评论