http协议中的controller层
在 @PostMapping("/login")中,我定义登录成功返回jwt令牌,保存用户id和用户名
String token = JWTUtils.generateToken(map);
return Result.success(token);
在拦截器中,我将jwt令牌加入到threadlocal中,那么http的不同线程都可以访问到用户名和id
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("Authorization");
try{
Map<String, Object> claims = JWTUtils.parseToken(token);
ThreadLocalUtils.set(claims);
return true;
}catch (Exception e){
response.setStatus(401);
return false;
}
}
但是在websocket中使用threadlocal解析想要拿到用户id作为在线聊天socket聊天的唯一标识却拿不到,为map为null,就像这样
package com.codeCart.websocket;
import com.codeCart.util.ThreadLocalUtils;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* WebSocket类是一个用于处理WebSocket通信的类。
*/
@ServerEndpoint("/websocket")
@Component
public class WebSocket {
/**
* 当WebSocket连接打开时调用的方法。
*
* @param session WebSocket会话对象
*/
private static final Map<Integer,Session> sessions = new HashMap<>();
private static int onLineUser = 0;
private Map<String,Object> map = ThreadLocalUtils.get();
@OnOpen
public void onOpen(Session session) {
System.out.println(map);
try{
onLineUser++;
sessions.put(onLineUser,session);
session.setMaxIdleTimeout(1000*60*60*24);
broadcastOnlineUser();
}catch (Exception e){
try {
session.close();
}catch (Exception x){
System.out.println("连接未正常关闭!"+x.getMessage());
}
System.out.println("session创建失败原因"+e.getMessage());
}
}
/**
* 当WebSocket连接关闭时调用的方法。
*
* @param session WebSocket会话对象
*/
@OnClose
public void onClose(Session session) {
sessions.remove(onLineUser);
onLineUser--;
broadcastOnlineUser();
}
/**
* 当接收到WebSocket消息时调用的方法。
*
* @param message WebSocket消息
* @param session WebSocket会话对象
*/
@OnMessage
public void onMessage(String message, Session session) {
try {
Session receivingSession = sessions.get(2);
receivingSession.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 当WebSocket发生错误时调用的方法。
*
* @param session WebSocket会话对象
* @param error WebSocket错误对象
*/
@OnError
public void onError(Session session, Throwable error) {
System.out.println("websocket error:" + error.getMessage());
}
public void broadcastOnlineUser() {
System.out.println("系统广播:当前在线用户数"+onLineUser);
}
}
ps:我也知道通过ws协议传参校验,然后解析可以实现,或者通过一些方式周转拿到http消息的信息可以实现,但是我现在觉得既然我都用了threadlocal了,能不能同一件事情只做一次,ws也可以得到threadlocal的变量值