1.maven坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.创建处理器
/**
* @author zhong
* webscoket 处理器
*/
@Component
public class CustomWebSocketHandler extends TextWebSocketHandler {
private static final Logger logger = LoggerFactory.getLogger(CustomWebSocketHandler.class);
/**
* 当前websocket连接集合
*/
public static final ConcurrentHashMap<String, WebSocketSession> WEB_SOCKET_SESSION_MAP = new ConcurrentHashMap<>();
/**
* 收到客户端消息时触发的回调
*
* @param session 连接对象
* @param message 消息体
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
logger.info("接受到消息【{}】的消息:{}", session.getId(), message.getPayload());
}
/**
* 建立连接后触发的回调
*
* @param session 连接对象
* @throws Exception
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String sessionId = getSessionId(session);
// 如果存在则断开连接
if (WEB_SOCKET_SESSION_MAP.containsKey(sessionId)) {
WEB_SOCKET_SESSION_MAP.get(sessionId).close();
}
// 将新连接添加
WEB_SOCKET_SESSION_MAP.put(sessionId, session);
logger.info("与【{}】建立了连接", sessionId);
sendMessage(sessionId, sessionId);
logger.info("attributes:{}", session.getAttributes());
}
/**
* 断开连接后触发的回调
*
* @param session 连接对象
* @param status 状态
* @throws Exception 异常
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
logger.info("连接对象【{}】断开连接,status:{}", getSessionId(session), status.getCode());
// 关闭连接
session.close(CloseStatus.SERVER_ERROR);
// 删除对象
WEB_SOCKET_SESSION_MAP.remove(getSessionId(session));
}
/**
* 传输消息出错时触发的回调
*
* @param session 连接对象
* @param exception 异常
* @throws Exception 异常
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
logger.info("连接对象【{}】发生错误,exception:{}", session.getId(), exception.getMessage());
// 如果发送异常,则断开连接
if (session.isOpen()) {
session.close();
}
WEB_SOCKET_SESSION_MAP.remove(getSessionId(session));
}
/**
* 自定义判断 sessionId
*
* @param session 连接对象
* @return sessionId
*/
private String getSessionId(WebSocketSession session) {
return (String) session.getAttributes().get("username");
}
/**
* 发送消息
*
* @param sessionId 对象id
* @param message 消息
* @throws IOException IO
*/
public void sendMessage(String sessionId, String message) throws IOException {
WebSocketSession webSocketSession = WEB_SOCKET_SESSION_MAP.get(sessionId);
if (webSocketSession == null || !webSocketSession.isOpen()) {
logger.warn("连接对象【{}】已关闭,无法送消息:{}", sessionId, message);
} else {
webSocketSession.sendMessage(new TextMessage(message));
logger.info("sendMessage:向{}发送消息:{}", sessionId, message);
}
}
/**
* 发送消息
*
* @param sessionId 对象id
* @param data 数据
* @throws IOException IO
*/
public void sendMessage(String sessionId, Object data) throws IOException {
sendMessage(sessionId, JSON.toJSONString(data));
}
/**
* 获取所有的连接对象ID
*
* @return ids
*/
public List<String> getSessionIds() {
Enumeration<String> keys = WEB_SOCKET_SESSION_MAP.keys();
List<String> ks = new ArrayList<>();
while (keys.hasMoreElements()) {
ks.add(keys.nextElement());
}
return ks;
}
}
3.创建拦截器
/**
* @author zhong
* 用来处理webscocket拦截器
*/
@Component
public class CustomWebsocketInterceptor extends HttpSessionHandshakeInterceptor {
private static final Logger logger = LoggerFactory.getLogger(CustomWebsocketInterceptor.class);
/**
* 建立连接时
*
* @param request the current request
* @param response the current response
* @param wsHandler the target WebSocket handler
* @param attributes the attributes from the HTTP handshake to associate with the WebSocket
* session; the provided attributes are copied, the original map is not used.
* @return
* @throws Exception
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
ServletServerHttpRequest req = (ServletServerHttpRequest) request;
ServletServerHttpResponse res = (ServletServerHttpResponse) response;
String token = req.getServletRequest().getParameter("token");
String username = req.getServletRequest().getParameter("username");
logger.info("建立连接....token:{} username:{}", token, username);
logger.info("attributes:{}", attributes);
attributes.put("token", token);
attributes.put("username", username);
/**
* 鉴权: return false 不通过
* response.setStatusCode(HttpStatus.UNAUTHORIZED);
* return false;
*/
super.setCreateSession(true);
return super.beforeHandshake(request, response, wsHandler, attributes);
}
/**
* 成功建立连接后
*
* @param request the current request
* @param response the current response
* @param wsHandler the target WebSocket handler
* @param exception an exception raised during the handshake, or {@code null} if none
*/
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
logger.info("连接成功....");
//其他业务代码
super.afterHandshake(request, response, wsHandler, exception);
}
}
3.创建配置文件
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Resource
private CustomWebsocketInterceptor customWebsocketInterceptor;
@Resource
private CustomWebSocketHandler customWebSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry
// 设置处理器处理/custom/**
.addHandler(customWebSocketHandler,"/custom")
// 允许跨越
.setAllowedOrigins("*")
// 设置监听器
.addInterceptors(customWebsocketInterceptor);
}
}
文章来源地址https://www.toymoban.com/news/detail-558320.html
文章来源:https://www.toymoban.com/news/detail-558320.html
到了这里,关于Springboot WebSocket鉴权,前处理(添加过滤器)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!