10

I am trying to implement a websocket on tomcat 7.0.50 using annotated endpoints as specified in Java Websocket API (1.0)- JSR 356. Following are the brief steps how I have coded it 1) Write a websocket endpoint using @ServerEndpoint annotation 2) implement @onOpen and @onMessage methods 3) open a websocket using javascript on google chrome.

Please find code corresponding to above steps in order

1) STEP 1 & 2 - writing websocket server endpoint:

        package com.jkweb.websocket;

       import java.io.IOException;
       import java.util.HashMap;
       import java.util.List;
       import java.util.Map;

       import javax.websocket.EndpointConfig;
       import javax.websocket.OnMessage;
       import javax.websocket.OnOpen;
       import javax.websocket.Session;
       import javax.websocket.server.PathParam;
       import javax.websocket.server.ServerEndpoint;

       import org.slf4j.Logger;
       import org.slf4j.LoggerFactory;

  @ServerEndpoint(value="/websocket/fileuploadtracker")

@OnOpen 
public void open(Session session,EndpointConfig config) {
    ......
}
@OnMessage
public void onMessage(Session session, String msg) {
    try {
        session.getBasicRemote().sendText(msg);
    } catch (IOException e) {
        logger.error(e.getMessage());
    }
}

public static void sendMessage(String uniqueTocken,String msg){
    try {
        Session wsSession = socketConnectionMap.get(uniqueTocken);
        wsSession.getBasicRemote().sendText(msg);
    } catch (IOException e) {
        logger.error(e.getMessage());
    }
}

}

2) STEP 3 - opening websocket using javascript api in chrome:

      wsurl =  "ws://localhost:8080/jkweb/websocket/fileuploadtracker",
        ws; 
        ws = new WebSocket(wsurl);
         ws.onopen = function()
         {
            // Web Socket is connected, send data using send()
            ws.send("Sending first Message");
            alert("Message is sent...");
         };
         ws.onmessage = function (evt) 
         { 
            var received_msg = evt.data;
            alert("Message is received...");
         };
         ws.onclose = function(evt)
         { 
            // websocket is closed.
            alert("Connection is closed..."+evt.code + ":"+evt.reason ); 
         };        

I am using following versions of softwares : 1) Tomcat - 7.0.50 2) Java - 1.7.45 3) Servlet - 3.0 4) Have included following Maven dependency 5) Chrome - 32.0.1700.107m

     <dependency>
     <groupId>javax.websocket</groupId>
     <artifactId>javax.websocket-api</artifactId>
     <version>1.0</version>
         <scope>provided</scope>
</dependency>   

However I am getting following error and connection is closed with 1066 error code in chrome's console:

      WebSocket connection to 'ws://localhost:8080/jkweb/websocket/fileuploadtracker' failed: Error during WebSocket handshake: Unexpected response code: 404

Is there any configuration I am missing out on. I tried to search a lot but couldn't find anything. Please I need this to be solved ASAP.

alseether
  • 1,889
  • 2
  • 24
  • 39
Shailesh Vaishampayan
  • 1,766
  • 5
  • 24
  • 52

3 Answers3

13

I have solved it. Problem was very specific to my installation. I had the websocket api .jar being installed in my app's WEB-INF/lib directory as well. Not sure why it was breaking it. can you put some light on the root cause of this behaviour and why it doesn't work when you gave websocket-api.jar in application's WEB-INF/lib along with tomcat's lib?

Shailesh Vaishampayan
  • 1,766
  • 5
  • 24
  • 52
  • 5
    I ran into the same problem, as soon as I set the dependency scope to provided it no longer threw the 404. Probably some duplicate class conflict or something that causes the annotation not to get read. – Brian Antonelli Mar 31 '14 at 19:25
  • Not so specific to your installation, since I ran into the same issue, too. – Kyrstellaine Apr 10 '14 at 23:54
  • right. But I put this on tomcat user list to know the cause noone really replied why? can you put some light o this? – Shailesh Vaishampayan Apr 11 '14 at 11:19
  • For someone learning this the first time, this was a major pain to solve - thank you! – ash Apr 23 '14 at 01:17
  • 1
    thank you very much! maven will pack websocket-api.jar by default, exclude the jar will solve the issue – zyanlu Dec 08 '14 at 04:43
  • @ShaileshVaishampayan could you share the working pom? I'm having the same issue – Thusitha Thilina Dayaratne Apr 26 '15 at 13:51
  • 3
    @ThusithaThilinaDayaratne I have already given correct and relevant maven configuration in my question. To solve the problem make sure you have configured "provided" scope for websocket api and your tomcat lib directory actually contains websocket-api.jar. Here is configuration again for you : javax.websocket javax.websocket-api 1.0 provided – Shailesh Vaishampayan Apr 27 '15 at 13:51
  • How can this be fixed when one uses Spring's websocket ? It's not like we can set scope=provided for the Spring websocket API ! ;( – niilzon Jul 30 '16 at 11:13
  • this question and answer was explicitly related to scenario when you are using tomcat's native implementation for websocket. If you are using spring (I suppose STOMP over web socket) you this solution might be irrelevant for you. May be you have some other config missing, I suggest read Spring's Docs a bit more carefully to see if you are missing anything. I used spring's STOMP over web socket thing in another project and it worked fine without major issues. – Shailesh Vaishampayan Jul 30 '16 at 19:30
2

If you used tomcat server which was created in eclipse, you should delete the old server and create a new one with tomcat 7.0.50. This is my solution. PS: My tomcat server is 7.0.53, and the old one is 7.0.21. Good luck to you~

kei
  • 21
  • 1
0

I also had the same problem. Try removing the unwanted jars which contains websocket in your $JAVA_HOME/lib folder. and then add only

mahem
  • 1
  • 1
  • 4