21

I am trying to run a demo of spring web socket but not able to test it completely. I am using java 7 and tomcat 7.0.50. I don't get any error while server startup, but when I open the web page with js making the connection to it I got 404 page not found. I am not sure if I am missing anything in configuration to make it run and how can I be able to connect it from js side.

I have following xml file:

<beans ....>
    <context:annotation-config />

    <websocket:message-broker
        application-destination-prefix="/app">
        <websocket:stomp-endpoint path="/hello">
            <websocket:sockjs />
        </websocket:stomp-endpoint>
        <websocket:simple-broker prefix="/topic" />
    </websocket:message-broker>
</beans>

My controller class is:

@Controller
public class SwsService {
    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
         return new Greeting("Hello, " + message.getName() + "!");
   }

    public String getGreeting() {
        return "Hello, you are in!";
    }
}

The js from which I am calling this is:

var sock = new SockJS("/hello");
sock.onopen = function () {
    console.log("open");
};
sock.onclose = function () {
    console.log("closed");
};
sock.onmessage = function (message) {
    console.log("msg", message);
};

The console output when I run the tomcat:

Feb 19, 2014 3:28:47 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre7\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files/Java/jre6/bin/client;C:/Program Files/Java/jre6/bin;C:/Program Files/Java/jre6/lib/i386;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files\TortoiseGit\bin;C:\Python24;C:\Program Files\TortoiseSVN\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Users\harsh\AppData\Roaming\npm;E:\IDE\eclipse_indigo;;.
Feb 19, 2014 3:28:47 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:SWS' did not find a matching property.
Feb 19, 2014 3:28:48 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Feb 19, 2014 3:28:48 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Feb 19, 2014 3:28:48 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1412 ms
Feb 19, 2014 3:28:48 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Feb 19, 2014 3:28:48 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.50
Feb 19, 2014 3:28:51 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Feb 19, 2014 3:28:51 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
Feb 19, 2014 3:28:51 PM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization started
Feb 19, 2014 3:28:51 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing Root WebApplicationContext: startup date [Wed Feb 19 15:28:51 IST 2014]; root of context hierarchy
Feb 19, 2014 3:28:52 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/classes/conf/SwsContext.xml]
Feb 19, 2014 3:28:53 PM org.springframework.scheduling.concurrent.ExecutorConfigurationSupport initialize
INFO: Initializing ExecutorService  'clientInboundChannelExecutor'
Feb 19, 2014 3:28:53 PM org.springframework.scheduling.concurrent.ExecutorConfigurationSupport initialize
INFO: Initializing ExecutorService  'clientOutboundChannelExecutor'
Feb 19, 2014 3:28:53 PM org.springframework.scheduling.concurrent.ExecutorConfigurationSupport initialize
INFO: Initializing ExecutorService  'messageBrokerSockJsScheduler'
Feb 19, 2014 3:28:53 PM org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler
INFO: Mapped URL path [/hello/**] onto handler of type [class org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler]
Feb 19, 2014 3:28:53 PM org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup start
INFO: Starting beans in phase 2147483647
Feb 19, 2014 3:28:53 PM org.springframework.web.context.ContextLoader initWebApplicationContext
INFO: Root WebApplicationContext: initialization completed in 2173 ms
Feb 19, 2014 3:28:53 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Feb 19, 2014 3:28:53 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Feb 19, 2014 3:28:53 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 5842 ms

The browser console output:

GET http://localhost:8080/hello/info 404 (Not Found) sockjs-0.3.min.js:27
closed 

How can I successfully test it?


Updates

I also tried running the portfolio example from here: https://github.com/rstoyanchev/spring-websocket-portfolio as suggested by @jhadesdev

But it also doesn't help. When I run mvn tomcat7:run, I see following output and open url on browser tells 404.

[INFO] Scanning for projects...
[INFO]
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethrea
ded.SingleThreadedBuilder with a thread count of 1
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building spring-websocket-portfolio 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> tomcat7-maven-plugin:2.2:run (default-cli) @ spring-websocket-portfol
io >>>
[INFO]
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ spring-web
socket-portfolio ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\libraries\spring-websocket-portfol
io\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ spring-websoc
ket-portfolio ---
[INFO] No sources to compile
[INFO]
[INFO] <<< tomcat7-maven-plugin:2.2:run (default-cli) @ spring-websocket-portfol
io <<<
[INFO]
[INFO] --- tomcat7-maven-plugin:2.2:run (default-cli) @ spring-websocket-portfol
io ---
[INFO] Running war on http://localhost:8080/spring-websocket-portfolio
[INFO] Using existing Tomcat server configuration at E:\libraries\spring-websock
et-portfolio\target\tomcat
[INFO] create webapp with contextPath: /spring-websocket-portfolio
Feb 27, 2014 10:20:46 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Feb 27, 2014 10:20:46 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Feb 27, 2014 10:20:46 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.47
Feb 27, 2014 10:20:49 AM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Feb 27, 2014 10:20:49 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]

It stuck there and doesn't go ahead.

Harry Joy
  • 58,650
  • 30
  • 162
  • 207
  • Hello Harry. I think that the problem is that you miss the root of your project when you create new SockJS object. You can try var sock = new SockJS("/myProject/hello"); or with c:url. – Evgeni Dimitrov Feb 19 '14 at 12:59
  • @Evgeni I tried that also, but still its saying 404. :( – Harry Joy Feb 20 '14 at 05:39
  • @HarryJoy - did you try with the full url also? – Olimpiu POP Mar 05 '14 at 07:24
  • regarding the portfolio example - which URLs are responding with 404? The app root (http://localhost:8080/spring-websocket-portfolio) ? Or the sockjs info endpoint (http://localhost:8080/spring-websocket-portfolio/portfolio/info) ? – Brian Clozel Mar 05 '14 at 09:15
  • Don't you have a second webserver running ? Two programs can't run on the same port at the same time normally, but let's try –  Mar 05 '14 at 10:08
  • @BrianClozel the second one, on which it tries to make a socket connection. – Harry Joy Mar 06 '14 at 04:20

7 Answers7

10

I was facing the same problem. This thread gave me enough clues to solve the problem. Thanks a lot.

SOLUTION: In case you have a Spring MVC Dispatcher Servlet configured in your web.xml and mapped to a url-pattern as shown below

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/webui/*</url-pattern>
</servlet-mapping>

Then you have to create the SockJS instance as shown below

var socket = new SockJS('/contextPath/webui/hello');

NOTE: Replace contextPath with your application context path.

user3901192
  • 101
  • 1
  • 3
  • Helped. thank you. I noticed when the example ran from Spring Boot jar file it worked ok but when converted to a war it indeed needed context path. – tomasz_kusmierczyk Nov 20 '15 at 17:34
2

This Chrome extension can help you test Websockets.

Also you can have a look at my simple-chat project that uses Spring Boot with Websockets.

Roadrunner
  • 6,661
  • 1
  • 29
  • 38
2

Try adding an assets folder inside webapp, where all the stomp and sockjs.js files are made available. Have a look at this example of a running application, that can be run with mvn clean install jetty:run.

The problem seems to be that either the sockjs is not on the server or some path is wrong. Based on the example on the link, a stomp endpoint can be configured like this:

@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/portfolio").withSockJS();
    }

}

Then in javascript the end point can be called like this:

 var socket = new SockJS('/spring-websocket-portfolio/portfolio')
 var stompClient = Stomp.over(socket);

where /spring-websocket-portfolio is the root deployment path of your application.

Angular University
  • 42,341
  • 15
  • 74
  • 81
1

Your application looks fine.

You should definitely prefix JavaScript requests with the root context of your application, as jhadesdev mentioned.

Does your application registers additional filters or customize messageconverters? Maybe some other element of configuration is interfering here.

The latest portfolio example should definitely work, here are some questions:

  1. Could you tell us more about your client setup (browser, version)?
  2. Does your browser support websocket (test it there)?
  3. Could you also try in incognito mode (maybe a 3rd party browser extension is at fault here)?
  4. Could you check that your browser is not using a HTTP proxy for localhost requests?
  5. Could you check if this HTTP 404 is in Tomcat access log? (and see if you've got something interesting in those or in catalina.out?)
Community
  • 1
  • 1
Brian Clozel
  • 56,583
  • 15
  • 167
  • 176
1

How is your DispatcherServlet mapped? Here might be what you're looking for

Community
  • 1
  • 1
dawidklos
  • 902
  • 1
  • 9
  • 32
0

I solved this problem in thats way: when you create the SockJS add localhost:8080/ like this

new SockJS('http://localhost:8080/spring-websocket-portfolio/portfolio')
tn2000
  • 642
  • 1
  • 8
  • 13
0

For me the solution was to enable SockJS in by WebSocketConfig class:

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/search")
            .setAllowedOrigins("*")
            .setHandshakeHandler(new DefaultHandshakeHandler())
            .withSockJS();
}
Bogdan Kobylynskyi
  • 1,150
  • 1
  • 12
  • 34