zyro23 / grails-spring-websocket

93 stars 28 forks source link

"Whoops! Lost connection to undefined" #21

Closed hoof closed 9 years ago

hoof commented 9 years ago

I am following your example, however I can't seem to get it to work.

                var socket = new SockJS("${createLink(uri: '/stomp')}");
                var client = Stomp.over(socket);

Seems to work ok - no output in the console. However, whenever I issue:

            client.connect({}, function() {
                client.subscribe("/topic/hello", function(message) {
                    $("#helloDiv").append(JSON.parse(message.body));
                });
            });

My browser outputs

Opening Web Socket...
Whoops! Lost connection to undefined

I have no idea, what to do now. I have tried different debug output without luck. Can you maybe give some input? Could URL-mappings cause a problem or should I manually do something with dispatcher config?

Many thanks in advance!

zyro23 commented 9 years ago

first you should check what url createLink is generating in your js, e.g.

console.log("${createLink(uri: '/stomp')}");

then, try accessing that endpoint suffixed with /info manually like http://localhost:8080/appName/stomp/info (or whatever url your app is located at). that should give you a http 200 response with a json body like

{"entropy":-341951417,"origins":["*:*"],"cookie_needed":true,"websocket":true}

does it work so far or do you already get errors there?

hoof commented 9 years ago

That works just fine - and I get a result just like yours...

zyro23 commented 9 years ago

same problem on all browsers?

zyro23 commented 9 years ago

ah and just to really rule the url stuff out please try passing the full url manually to SockJS like:

var socket = new SockJS("http://localhost:8080/appName/stomp");
hoof commented 9 years ago

So. I found the problem. It relates to our login-security, which is a reverse proxy. If I connect directly on 8080 there is no problem. But if i connect throuch https on port 8443 (even if im setting the SockJS to localhost:8080) it wommits. Changing it to localhost:8443 makes it unable to connect at all. I need to work on this and maybe allowing /stomp/\ on port 8080 through our reverse proxy..

Thanks for the help!

ApoorvBarwa commented 7 years ago

Hi zyro ...i am facing the same problem .... but am not able to figure out why .... i used both the default setting and the url with localhost mentioned in it ... still get the same error ... I am using Grails 3 and have installed compile 'org.grails.plugins:grails-spring-websocket:2.2.0' in my dependencies.

I have a controller method(update1) at the end of which i am calling a service method which has the brokerMessagingTemplate bean ..... below is my code .... any help would be appreciated .....

Controller Code

def update1 () {

       // some action
......
        render "success"
        updateService.serverUpdate

    }

Service Code:

@Transactional
class UpdateService {
    SimpMessagingTemplate brokerMessagingTemplate

    def serverUpdate() {
        def message = "Hello From Server"
        brokerMessagingTemplate.convertAndSend "/topic/update" + message
    }
}

default SOCKJS code:

var ws = new SockJS("${createLink(uri: '/stomp')}");
var wsClient = Stomp.over(ws);
var subscribedMessage;

wsClient.connect({}, function(){
  subscribedMessage = client.subscribe("/topic/update", function(message){
    console.log("Message from Server is " + message.body)
  })
})

error in console:
http://localhost:8080/ops/$%7BcreateLink(uri:%20'/stomp')%7D/info 404 (Not Found)
Whoops! Lost connection to undefined

Full url SockJs Code:


var ws = new SockJS("http://localhost:8080/ops");
var wsClient = Stomp.over(ws);
var subscribedMessage;

wsClient.connect({}, function(){
  subscribedMessage = client.subscribe("/topic/update", function(message){
    console.log("Message from Server is " + message.body)
  })
})

error in console:
http://localhost:8080/ops/info 404 (Not Found)
Whoops! Lost connection to undefined

What am i doing wrong ... Could you please help

zyro23 commented 7 years ago

where is your js code located? http://localhost:8080/ops/$%7BcreateLink(uri:%20'/stomp')%7D/info 404 (Not Found) looks like the gsp ${} expression is not evaluated. if you put the js code into a js file or rather not directly into a gsp, you will have to put in the url hardcoded or pass it in by just defining the corresponding variable in your gsp.

var ws = new SockJS("http://localhost:8080/stomp");

note the endpoint /stomp in contrast to your /ops - or did you really re-map the stomp endpoint to /ops ?

ApoorvBarwa commented 7 years ago

Yes i have put the JS code in a JS file and am calling it using assets .... below is my application.js file

//= require ops/spring-websocket.js
//= require ops/ops.js

The Code in ops.js now looks like below

var ws = new SockJS("http://localhost:8080/stomp");
var wsClient = Stomp.over(ws)
var subscribedMessage 
wsClient.connect({}, function(){
  subscribedMessage = client.subscribe("/topic/update", function(message){
    console.log("Message from Server is " + message.body)
  })
})

GET http://localhost:8080/stomp/info 403 (Forbidden)
AbstractXHRObject._start @ sockjs.js?compile=false:807
(anonymous) @ sockjs.js?compile=false:841
sockjs.js?compile=false:807 XHR finished loading: GET "http://localhost:8080/stomp/info".
AbstractXHRObject._start @ sockjs.js?compile=false:807
(anonymous) @ sockjs.js?compile=false:841
stomp.js?compile=false:145 Whoops! Lost connection to undefined

I have stomp.js and sock.js in the folder containing spring-websocket.js .... should i include those files as well?? or do i need to create an endpoint using grails create-endpoint stomp ??

zyro23 commented 7 years ago

where is your application running? under contextPath /ops? or is that just an assets directory?

what do you see if you go to the url http://localhost:8080/stomp/info now manually?

ApoorvBarwa commented 7 years ago

My application is running at http://localhost:8080 ... below is the what appears in the console when i start the application Grails application running at http://localhost:8080 I have an Ops controller which i am trying to access by http://localhost:8080/ops when i try to go to the url http://localhost:8080/stomp/info i get a spring security error saying that you are not authorized to view this page .... dont know what i am doing wrong

zyro23 commented 7 years ago

that means that you first have to allow access to /stomp/info in your application.yml spring security config:

grails:
    plugin:
        springsecurity:
            controllerAnnotations:
                staticRules:
                    - {pattern: /stomp/**, access: [permitAll]}

or the correct role for your application instead of permitAll.

ApoorvBarwa commented 7 years ago

That didnt work for me either ..... will upload the code and would let you know .... thanks for your help

ApoorvBarwa commented 7 years ago

This is the url to my project .... https://github.com/ApoorvBarwa/testingWebSockets ..... The controller method is under cm/OpsController.groovy/updateCrqStatus(method) The js file is in assets/javascript/ops/ops.js The service method is services/cm .... UpdateService.groovy

Hope this helps .... i have not included conf directory as that contained server/ldap information

zyro23 commented 7 years ago

sorry but there is too much noise in that code not related to your websocket issue.

please raise a new issue and reference/attach a minimal runnable sample app that reproduces the problem.

then i can fork that one, fix it if necessary and give you a pull-req which will have a diff depicting the issue.

anyway i am almost certain that your issue does not originate from the plugin and/or spring websocket but your usage respectively your application.

so if i may suggest you start the sample app with the sample code from the grails-spring-websocket readme and then put your app-specifics in place one-by-one, like

thanks.

ApoorvBarwa commented 7 years ago

Ok will try that out ..... thanks for your help

ApoorvBarwa commented 7 years ago

Hey ... i finally got what the problem was ... although i need to work around that .... it was the spring security that was causing the problem .... i removed the plugin and then a websocket connection was established .... although since i am sending the message from a service i am now getting an error No 'defaultDestination' configured

ApoorvBarwa commented 7 years ago

I created a new test application with the code in the readme section of grails-spring-websockets ... i am facing another issue as i am getting response from the controller but not from the service .... i have uploaded the code in the following url .... i know i might be a pain here but i really need your help in understanding this fully .... https://github.com/ApoorvBarwa/testWebSockets .... or would you still want me to close this thread and start a new one as you mentioned earlier

ApoorvBarwa commented 7 years ago

Ok so i even got it to work with service but in a different way than you have suggested in the readme .... it is basically through an ajax call to the controller which in turn calls the service i created. But still i am not able to understand why am i getting a response from the server 4 times in each case ....

zyro23 commented 7 years ago

sample app is not working ootb (at least the websocket connection doesnot). server.port has to be adjusted to 8181?

you included application.js once in layouts/main.gsp and once in example/index.gsp causing weird double initialization of the javascript resulting in multiple websocket subscriptions.

hope that explains it? again, this is not an issue with this plugin but rather a matter of proper use of asset-pipeline.

if you got further questions regarding the general use of the plugin, the grails slack community and/or stackoverflow (tags grails and websocket) are a better fit with a larger audience.

ApoorvBarwa commented 7 years ago

Not required anymore.... my problem is solved and thanks alot for your help ....

keshav4u commented 5 years ago

g the full url manually to SockJS li

WTF. What a change you have suggested.