由于无效的升级标头,Spring Boot Websockets 握手失败:null

Posted

技术标签:

【中文标题】由于无效的升级标头,Spring Boot Websockets 握手失败:null【英文标题】:Spring boot Websockets Handshake failed due to invalid Upgrade header: null 【发布时间】:2021-11-11 05:17:38 【问题描述】:

我正在使用 spring boot 2.1.6 RELEASE,尝试使用 Stomp websockets 进行推送通知。我从这里参考:https://github.com/netgloo/spring-boot-samples/tree/master/spring-boot-web-socket-user-notification

在我当地一切正常。当部署到使用 HTTPS 连接的服务器时,我在日志中看到的只是这个。

Handshake failed due to invalid Upgrade header: null

在浏览器上

Websocket.js:6 WebSocket connection to 'wss://dev.myserver.in/ws/055/chbvjkl4/websocket' failed

我浏览了几十篇 *** 帖子,几乎每个人都在使用代理服务器。我没有使用任何代理服务器。 (请让我知道我是否应该使用一个以及为什么)

代码sn-ps:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer 

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) 
        registry.addEndpoint("/ws").withSockJS();
    


这是我现在允许 websocket 请求的方式

@Override
    public void configure(WebSecurity web) throws Exception 

        // Tell Spring to ignore securing the handshake endpoint. This allows the
        // handshake to take place unauthenticated
        web.ignoring().antMatchers("/ws/**");

    

将在特定操作上调用的推送通知服务:

@Service
public class PushNotificationService 

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;
    
    /**
     * Send notification to users subscribed on channel "/user/queue/notify".
     * The message will be sent only to the user with the given username.
     * 
     * @param notification The notification message.
     * @param username     The username for the user to send notification.
     */
    public void sendPushNotification(Notifications notification, String username) 
        simpMessagingTemplate.convertAndSendToUser(username, "/queue/notify", notification);
        return;
    

在前端:

function connect() 
        // Create and init the SockJS object
        var socket = new SockJS('/ws');
        var stompClient = Stomp.over(socket);

        // Subscribe the '/notify' channel
        stompClient.connect(, function(frame) 
          stompClient.subscribe('/user/queue/notify', function(notification) 
            notify(JSON.parse(notification.body));

          );
        );

这是通知

function notify(message) 
    let notificationTitle = message.status;
    let body = message.createdOn;
    let link = message.url;
    if(Notification.permission === "granted") 
        showPushNotification(notificationTitle,body,link);
    
    else 
        Notification.requestPermission(permission => 
            if(permission === 'granted') 
                showPushNotification(notificationTitle,body,link);
            
        );
    

【问题讨论】:

【参考方案1】:

如果你不使用nginx代理,你应该配置spring boot支持https

【讨论】:

以上是关于由于无效的升级标头,Spring Boot Websockets 握手失败:null的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Boot 的 starter web parent 时出现无效的打包错误

预检响应具有无效的 HTTP 状态代码 403 + angular 2 + Java Spring boot

如何使用 Spring Boot 和 Angular 应用程序隐藏授权标头

使用 Spring Boot 2 WebClient 从响应中获取标头

将 Web 应用升级到 Spring Boot 2.4 后出现 IllegalStateException

如何在使用 Angular 7 和 Spring Boot 构建的 Web 应用程序中使浏览器缓存无效