feat: websocket stomp 添加对 ws 连接协议支持(uni-app原生)

This commit is contained in:
haoxr
2023-10-17 21:51:53 +08:00
parent 652bc18fd2
commit 36894b16f1
4 changed files with 76 additions and 16 deletions

View File

@@ -1,6 +1,6 @@
package com.youlai.system.config; package com.youlai.system.config;
import com.youlai.system.websocket.interceptor.AuthChannelInterceptor; import com.youlai.system.interceptor.WebsocketChannelInterceptor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -22,7 +22,7 @@ import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerCo
@RequiredArgsConstructor @RequiredArgsConstructor
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private final AuthChannelInterceptor authChannelInterceptor; private final WebsocketChannelInterceptor websocketChannelInterceptor;
/** /**
* 注册一个端点,客户端通过这个端点进行连接 * 注册一个端点,客户端通过这个端点进行连接
@@ -32,8 +32,8 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
registry registry
.addEndpoint("/ws") // 注册了一个 /ws 的端点 .addEndpoint("/ws") // 注册了一个 /ws 的端点
.setAllowedOriginPatterns("*") // 允许跨域的 WebSocket 连接 .setAllowedOriginPatterns("*") // 允许跨域的 WebSocket 连接
.withSockJS() // 启用 SockJS (浏览器不支持WebSocketSockJS 将会提供兼容性支持) .withSockJS(); // 启用 SockJS (浏览器不支持WebSocketSockJS 将会提供兼容性支持)
; registry.addEndpoint("/ws-app").setAllowedOriginPatterns("*"); // 注册了一个 /ws-app 的端点,支持 uni-app 的 ws 连接协议
} }
@@ -60,6 +60,6 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
*/ */
@Override @Override
public void configureClientInboundChannel(ChannelRegistration registration) { public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(authChannelInterceptor); registration.interceptors(websocketChannelInterceptor);
} }
} }

View File

@@ -1,6 +1,6 @@
package com.youlai.system.websocket; package com.youlai.system.controller;
import com.youlai.system.websocket.dto.MessageDTO; import com.youlai.system.model.dto.SocketMessage;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.DestinationVariable; import org.springframework.messaging.handler.annotation.DestinationVariable;
@@ -51,7 +51,7 @@ public class WebsocketController {
//@SendToUser(value = "/queue/greeting") //@SendToUser(value = "/queue/greeting")
public void sendToUser(Principal principal, @DestinationVariable String username, String message) { public void sendToUser(Principal principal, @DestinationVariable String username, String message) {
log.info("sender:{};receiver:{}", principal.getName(), username); log.info("sender:{};receiver:{}", principal.getName(), username);
messagingTemplate.convertAndSendToUser(username, "/queue/greeting", new MessageDTO(principal.getName(), message)); messagingTemplate.convertAndSendToUser(username, "/queue/greeting", new SocketMessage(principal.getName(), message));
/// return "Hello, " + message; /// return "Hello, " + message;
} }

View File

@@ -1,4 +1,4 @@
package com.youlai.system.websocket.interceptor; package com.youlai.system.interceptor;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.youlai.system.security.jwt.JwtTokenProvider; import com.youlai.system.security.jwt.JwtTokenProvider;
@@ -21,7 +21,7 @@ import java.security.Principal;
*/ */
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class AuthChannelInterceptor implements ChannelInterceptor { public class WebsocketChannelInterceptor implements ChannelInterceptor {
private final JwtTokenProvider jwtTokenProvider; private final JwtTokenProvider jwtTokenProvider;
@@ -38,14 +38,10 @@ public class AuthChannelInterceptor implements ChannelInterceptor {
assert accessor != null; assert accessor != null;
if (StompCommand.CONNECT.equals(accessor.getCommand())) { if (StompCommand.CONNECT.equals(accessor.getCommand())) {
// get token from header
String bearerToken = accessor.getFirstNativeHeader("Authorization"); String bearerToken = accessor.getFirstNativeHeader("Authorization");
// if token is not null
if (StrUtil.isNotBlank(bearerToken)) { if (StrUtil.isNotBlank(bearerToken)) {
bearerToken = bearerToken.substring(7); // remove "Bearer "
bearerToken = bearerToken.substring(7);
String username = jwtTokenProvider.getUsername(bearerToken); String username = jwtTokenProvider.getUsername(bearerToken);
// if the username is not null, assign it to the Principal.
if (StrUtil.isNotBlank(username)) { if (StrUtil.isNotBlank(username)) {
Principal principal = () -> username; Principal principal = () -> username;
accessor.setUser(principal); accessor.setUser(principal);

View File

@@ -0,0 +1,64 @@
package com.youlai.system.listener.websocket;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectedEvent;
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
import org.springframework.web.socket.messaging.SessionSubscribeEvent;
import org.springframework.web.socket.messaging.SessionUnsubscribeEvent;
/**
* Websocket 客户端事件监听器
*
* @author haoxr
* @since 2023/10/10
*/
@Component
@Slf4j
public class WebSocketEventListener {
/**
* 监听客户端连接事件
*
* @param event 连接事件对象
*/
@EventListener
public void handleWebSocketConnectListener(SessionConnectedEvent event) {
log.info("客户端连接成功");
}
/**
* 监听客户端断开连接事件
*
* @param event 断开连接事件对象
*/
@EventListener
public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
log.info("客户端断开连接");
}
/**
* 监听客户端订阅事件
*
* @param event 订阅事件对象
*/
@EventListener
public void handleSubscription(SessionSubscribeEvent event) {
log.info("客户端订阅:{}", JSONUtil.toJsonStr(event.getMessage()));
}
/**
* 监听客户端取消订阅事件
*
* @param event 取消订阅事件对象
*/
@EventListener
public void handleUnSubscription(SessionUnsubscribeEvent event) {
log.info("客户端取消订阅:{}", JSONUtil.toJsonStr(event.getMessage()));
}
}