parent
542d11370c
commit
2f4cc28e83
@ -1,103 +0,0 @@ |
|||||||
package com.bellmann.config; |
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil; |
|
||||||
import cn.hutool.jwt.JWTPayload; |
|
||||||
import com.bellmann.security.util.JwtUtils; |
|
||||||
import lombok.extern.slf4j.Slf4j; |
|
||||||
import org.springframework.context.annotation.Configuration; |
|
||||||
import org.springframework.http.HttpHeaders; |
|
||||||
import org.springframework.messaging.Message; |
|
||||||
import org.springframework.messaging.MessageChannel; |
|
||||||
import org.springframework.messaging.simp.config.ChannelRegistration; |
|
||||||
import org.springframework.messaging.simp.config.MessageBrokerRegistry; |
|
||||||
import org.springframework.messaging.simp.stomp.StompCommand; |
|
||||||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor; |
|
||||||
import org.springframework.messaging.support.ChannelInterceptor; |
|
||||||
import org.springframework.messaging.support.MessageHeaderAccessor; |
|
||||||
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; |
|
||||||
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; |
|
||||||
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; |
|
||||||
|
|
||||||
/** |
|
||||||
* WebSocket 配置 |
|
||||||
* |
|
||||||
* |
|
||||||
* @since 2.4.0 |
|
||||||
*/ |
|
||||||
@Configuration |
|
||||||
@EnableWebSocketMessageBroker // 启用WebSocket消息代理功能和配置STOMP协议,实现实时双向通信和消息传递
|
|
||||||
@Slf4j |
|
||||||
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { |
|
||||||
|
|
||||||
/** |
|
||||||
* 注册一个端点,客户端通过这个端点进行连接 |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void registerStompEndpoints(StompEndpointRegistry registry) { |
|
||||||
registry |
|
||||||
.addEndpoint("/ws") // 注册了一个 /ws 的端点
|
|
||||||
.setAllowedOriginPatterns("*") // 允许跨域的 WebSocket 连接
|
|
||||||
.withSockJS(); // 启用 SockJS (浏览器不支持WebSocket,SockJS 将会提供兼容性支持)
|
|
||||||
registry.addEndpoint("/ws-app").setAllowedOriginPatterns("*"); // 注册了一个 /ws-app 的端点,支持 uni-app 的 ws 连接协议
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 配置消息代理 |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void configureMessageBroker(MessageBrokerRegistry registry) { |
|
||||||
// 客户端发送消息的请求前缀
|
|
||||||
registry.setApplicationDestinationPrefixes("/app"); |
|
||||||
|
|
||||||
// 客户端订阅消息的请求前缀,topic一般用于广播推送,queue用于点对点推送
|
|
||||||
registry.enableSimpleBroker("/topic", "/queue"); |
|
||||||
|
|
||||||
// 服务端通知客户端的前缀,可以不设置,默认为user
|
|
||||||
registry.setUserDestinationPrefix("/user"); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 配置客户端入站通道拦截器 |
|
||||||
* <p> |
|
||||||
* 添加 ChannelInterceptor 拦截器,用于在消息发送前,从请求头中获取 token 并解析出用户信息(username),用于点对点发送消息给指定用户 |
|
||||||
* |
|
||||||
* @param registration 通道注册器 |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public void configureClientInboundChannel(ChannelRegistration registration) { |
|
||||||
registration.interceptors(new ChannelInterceptor() { |
|
||||||
@Override |
|
||||||
public Message<?> preSend(Message<?> message, MessageChannel channel) { |
|
||||||
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); |
|
||||||
// 如果是连接请求(CONNECT 命令),从请求头中取出 token 并设置到认证信息中
|
|
||||||
if (accessor != null && StompCommand.CONNECT.equals(accessor.getCommand())) { |
|
||||||
// 从连接头中提取授权令牌
|
|
||||||
String bearerToken = accessor.getFirstNativeHeader(HttpHeaders.AUTHORIZATION); |
|
||||||
|
|
||||||
// 验证令牌格式并提取用户信息
|
|
||||||
if (StrUtil.isNotBlank(bearerToken) && bearerToken.startsWith("Bearer ")) { |
|
||||||
try { |
|
||||||
// 移除 "Bearer " 前缀,从令牌中提取用户信息(username), 并设置到认证信息中
|
|
||||||
|
|
||||||
// 这里不应该用"name"
|
|
||||||
// String username = JwtUtils.parseToken(bearerToken).get("name").toString();
|
|
||||||
String username = JwtUtils.parseToken(bearerToken).get(JWTPayload.SUBJECT).toString(); |
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(username)) { |
|
||||||
accessor.setUser(() -> username); |
|
||||||
return message; |
|
||||||
} |
|
||||||
} catch (Exception e) { |
|
||||||
log.error("Failed to process authentication token.", e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
// 不是连接请求,直接放行
|
|
||||||
return ChannelInterceptor.super.preSend(message, channel); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,61 +0,0 @@ |
|||||||
package com.bellmann.controller; |
|
||||||
|
|
||||||
import com.bellmann.model.dto.ChatMessage; |
|
||||||
import lombok.RequiredArgsConstructor; |
|
||||||
import lombok.extern.slf4j.Slf4j; |
|
||||||
import org.springframework.messaging.handler.annotation.DestinationVariable; |
|
||||||
import org.springframework.messaging.handler.annotation.MessageMapping; |
|
||||||
import org.springframework.messaging.handler.annotation.SendTo; |
|
||||||
import org.springframework.messaging.simp.SimpMessagingTemplate; |
|
||||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||||
import org.springframework.web.bind.annotation.RestController; |
|
||||||
|
|
||||||
import java.security.Principal; |
|
||||||
|
|
||||||
/** |
|
||||||
* WebSocket 测试控制器 |
|
||||||
* |
|
||||||
* |
|
||||||
* @since 2.3.0 |
|
||||||
*/ |
|
||||||
@RestController |
|
||||||
@RequestMapping("/websocket") |
|
||||||
@RequiredArgsConstructor |
|
||||||
@Slf4j |
|
||||||
public class WebsocketController { |
|
||||||
|
|
||||||
private final SimpMessagingTemplate messagingTemplate; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 广播发送消息 |
|
||||||
* |
|
||||||
* @param message 消息内容 |
|
||||||
*/ |
|
||||||
@MessageMapping("/sendToAll") |
|
||||||
@SendTo("/topic/notice") |
|
||||||
public String sendToAll(String message) { |
|
||||||
return "服务端通知: " + message; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 点对点发送消息 |
|
||||||
* <p> |
|
||||||
* 模拟 张三 给 李四 发送消息场景 |
|
||||||
* |
|
||||||
* @param principal 当前用户 |
|
||||||
* @param username 接收消息的用户 |
|
||||||
* @param message 消息内容 |
|
||||||
*/ |
|
||||||
@MessageMapping("/sendToUser/{username}") |
|
||||||
public void sendToUser(Principal principal, @DestinationVariable String username, String message) { |
|
||||||
|
|
||||||
String sender = principal.getName(); // 发送人
|
|
||||||
String receiver = username; // 接收人
|
|
||||||
|
|
||||||
log.info("发送人:{}; 接收人:{}", sender, receiver); |
|
||||||
// 发送消息给指定用户,拼接后路径 /user/{receiver}/queue/greeting
|
|
||||||
messagingTemplate.convertAndSendToUser(receiver, "/queue/greeting", new ChatMessage(sender, message)); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,14 @@ |
|||||||
|
package com.bellmann.model.form; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
@Data |
||||||
|
public class PwdForm { |
||||||
|
|
||||||
|
|
||||||
|
private String oldPwd; |
||||||
|
|
||||||
|
private String newPwd; |
||||||
|
|
||||||
|
private String lastPwd; |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.bellmann.model.vo; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
@Data |
||||||
|
public class OperateTaskResultVO { |
||||||
|
|
||||||
|
private Long operTaskId; |
||||||
|
|
||||||
|
private String userName; |
||||||
|
|
||||||
|
private String errorDesc; |
||||||
|
|
||||||
|
private String resultState; |
||||||
|
|
||||||
|
private Date operTaskCreateTime; |
||||||
|
|
||||||
|
private Date operStartTime; |
||||||
|
|
||||||
|
private Date operEndTime; |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue