首先上组件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
然后实现:
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer
最关键的是
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins(allowedOrigins.split(","))
// 握手阶段把 URL 上的 token 存进 session attributes(鉴权兜底通道)
.addInterceptors(tokenHandshakeInterceptor())
.withSockJS()
.setSessionCookieNeeded(false)
// SockJS 层心跳 25s:SockJS 在 http 轮询降级时靠它保活
.setHeartbeatTime(25_000)
.setTaskScheduler(heartbeatScheduler())
.setDisconnectDelay(30_000);
}
其中必须写明具体Origins,写* 一定前端跨域失败(前端底层自身问题)
实现
public class WebSocketAuthInterceptor implements ChannelInterceptor 进行token校验
实现后台发送类:
public class LocalStompPublisher
其中:
public String send(PushEnvelope envelope) {
try {
String destination = envelope.getDestination();
// 投递前先看有没有订阅者
int subscribers = subscriptionTracker.count(destination);
if (subscribers == 0) {
CommonsUtil.debugLog("destination=" + destination + " 当前无订阅者");
} else {
messagingTemplate.convertAndSend(destination, envelope.getPayloadJson());
CommonsUtil.debugLog("本地投递成功 destination=" + destination);
}
return "";
} catch (Exception e) {
CommonsUtil.recordLog(e);
return "ERROR:" + e.getMessage();
}
}