Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incompatibile SockJS! Main site uses: "1.1.4", the iframe: "1.0.0". How to deal with that?

I have problem with WebSocket using SpringBoot and Angular2:

Incompatibile SockJS! Main site uses: "1.1.4", the iframe: "1.0.0".

Screenshot: consoleOutput

I think that error (Incompatibile SockJS! Main site uses: "1.1.4", the iframe: "1.0.0".) generate next problems with handshake response.

Spring Boot:

WebSocket Config

package com.example.demo;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;

@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/socket").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/chat");
        registry.setApplicationDestinationPrefixes("/app");
    }
}

Controller

package com.example.demo;


import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class WebSocketController {

    @MessageMapping("/send/message") 
    @SendTo("/chat/greetins")
    public String onReceivedMessage(String message) {
        return message;
    }
}

Angular2

import { Component, OnInit } from '@angular/core';
import   * as Stomp  from 'stompjs';
import  * as SockJS   from 'sockjs-client';
import * as $ from 'jquery';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
    private serverUrl = "/api/socket";
    private title = "WebSockets chat";
    private stompClient;

    constructor() {

    }

    ngOnInit() {
        this.initializeWebSocketConnection();   
    }

    initializeWebSocketConnection() {
        var ws = new SockJS(this.serverUrl);
        this.stompClient = Stomp.over(ws);
        let that = this;
        this.stompClient.connect({}, function(frame) {
            console.log("Connection Success.");
            that.stompClient.subscribe("/chat/greetings", (message) => {
                if (message.body) {
                    $(".chat").append("<div class='message'>" + message.body + "</div>");
                }
            });
        } );
    }

    sendMessage() {
        let message = $('#input').val(); 
        this.stompClient.send("app/send/message", {}, message);
        $('#input').val('');
    }
}

Thanks for help.

like image 377
scorpion Avatar asked Jan 30 '18 15:01

scorpion


3 Answers

I fixed it by manually hardcoding the SockJS version on the server-side (Spring/Java) by

@Override
public void registerStompEndpoints( StompEndpointRegistry registry ) 
{
     registry.addEndpoint( "/socket" )
        .setAllowedOrigins( "*" )
        .withSockJS( )
        .setClientLibraryUrl( "https://cdn.jsdelivr.net/sockjs/1.1.4/sockjs.min.js" ); 
}

Update: To load the JS library (local) using a relative path

@Override
public void registerStompEndpoints( StompEndpointRegistry registry )
{
   registry.addEndpoint( "/socket" )
       .setAllowedOrigins( "*" )
       .withSockJS( )
       .setClientLibraryUrl( "../lib/sockjs-client/dist/sockjs.min.js" ); // Added
}
like image 75
mani_jena Avatar answered Nov 13 '22 11:11

mani_jena


The version used in the iframe is a server setting

You need to change the sockjs_url parameter when creating the server to match the version you are serving on the front end.

like image 34
Léo R. Avatar answered Nov 13 '22 11:11

Léo R.


Your issue is probably related to missing Upgrade request header from your client. You can check your Tomcat logs and try to find something like this:

Handshake failed due to invalid Upgrade header: null

This is because the upgrade header is not passed from Nginx/Appache Http Server to Spring. This header is required to handshake connection between client and server via WebSockets. You can find more info about WebSocket handshake here:

https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers

So, check your load balancer or http server configuration. Check similar issue below with sample Nginx configuration:

https://github.com/sockjs/sockjs-client/issues/388

Sample Nginx configurations:

location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;

# For WebSocket upgrade header
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

}

like image 21
KRRySS Avatar answered Nov 13 '22 10:11

KRRySS