Spring 4 AbstractWebSocketMessageBrokerConfigurer With SockJS Not Negotiating Transport Properly

前提是你 提交于 2019-12-04 06:41:12

Given that it works in FF and in IE with sessionCookieNeeded=false I would guess the issue has to do with the X-Frame-Options header.

Your configuration seems right. Specifically this for Spring Security:

        .headers().addHeaderWriter(
            new XFrameOptionsHeaderWriter(
                    XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)).and()

and also this for SockJS:

            setClientLibraryUrl("http://localhost:8084/swtc/js/sockjs-0.3.4.min.js");

I suggest trying to disable the header just to confirm if it is the issue, i.e.:

        .headers().and()

Also make sure that there is no browser caching issue involved that's sending the same response back. So check the actual response headers for the value of X-Frame-Options.

For that I strongly suggest enabling the SockJS client debug mode through the options parameter of the SockJS constructor.

Since SockJS was producing a weird string error when attempting the WebSocket connection, then fell back to xhr_streaming, I decided to load up the non-minified version of the .js file and debug it in Firebug to see what was going on. Turns out, SockJS does not like relative URLs, which kind of stinks.

For most of my REST/AJAX services, I have /rest/* mapped to my dispatcher servlet, typically have an @RequestMapping on each controller, and another @RequestMapping on each controller method. Using Dojo, I make AJAX calls by specifying the url "rest/<controller>/<method>".

I was attempting the same thing with SockJS. I was just pointing to "rest/hello". I changed this to the fully qualified URL "http://localhost:8084/swtc/rest/hello" and suddenly firefox could build the websocket transport layer just fine. I hopped over to IE for a quick test and sure enough, it built the iframe session and also worked just fine.

Such a silly little problem. I hate having to specify non-relative urls anywhere, as this code base is shared between multiple developers, all who deploy to different servers for testing, and deploy to production. I suppose on the front-end I can dynamically build the URL using window.doc.URL, but it'll be a bit more tricky to get the AbstractWebSocketMessageBrokerConfigurer to automatically work across deployments when specifying setClientLibraryUrl.

Either way kids, don't use relative paths with SockJS.

I have found issues with IE9 also today after some investigation I found I needed to pass in a devel option into the call to create SockJS.

var protocols = { protocols_whitelist: ["websocket", "xhr-streaming", "xdr-streaming", "xhr-polling", "xdr-polling", "iframe-htmlfile", "iframe-eventsource", "iframe-xhr-polling"]};
var opt = {debug: false, devel: true}
var socket = new SockJS('/Application/wscomms', protocols, opt);
var stompClient = Stomp.over(socket);

Inside the sockjs-0.3.4.js file (at line 1749) I found a time gets appended to the iFrame URL

if (that.ri._options.devel) {
    iframe_url += '?t=' + (+new Date);
}

I noticed the develop option is set to false if not passed in as an option.

You will also notice that I am able to pass in a relative URL to SockJS which is working. I also have the same Spring Security config and WebSocketConfig setClientLibraryUrl() as shown by Rossen.

I have also found I am able to have

.setSessionCookieNeeded(true);

I am using Spring 4.0.1, Spring Security 3.2.0 and sockjs 0.3.4 and Tomcat 7.0.53

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!