I had recently implemented websocket on tomcat 7.0.50. my tomcat runs
behind apache 2.4. I use Strtus 2 and Spring Security. It has stopped
working.
Problem : Websocket connection is opened successfully. Javascript event
handler get fires successfully. Apache logs show that request was accepted
as an protocol upgrade request with 101 code Tomcat access logs also show
the same code 101 for protocol upgrade
However on server side onOpen message is not fired. I tried sending the
message as soon as connection is opened in javascript's event handler..
There is no error in javascript but Server side endPoint's onmessage is
never called just like onOpen is never called.
Here are the changes I made after which it has stopped working:
Windows Host file : I use dummy host name through Windows host file:
127.0.0.1 phasingapp.com
127.0.0.1 pricer.com
URL of wesocket :
old : ws://localhost:86/websocket/filuploadtrackerendpoint
new : ws://phasingapp.com:86/websocket/filuploadtrackerendpoint
Added virtual host config for apache :
<Location /jkweb/websocket/>
Require host phasingapp.com granted
</Location>
JkMount /jkweb/* localtomcat
JkUnMount /jkweb/project/content/* localtomcat
JkUnMount /jkweb/angle/content/* localtomcat
JkUnMount /jkweb/index.jsp localtomcat
JkUnMount /jkweb/ localtomcat
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /jkweb !
ProxyPass /jkweb/ !
ProxyPass /jkweb/websocket/ ws://localhost:8080/jkweb/websocket/
ProxyPassReverse /jkweb/websocket/ ws://localhost:8080/jkweb/websocket/
ProxyPass / http://localhost:8080/jkweb/
ProxyPassReverse / http://localhost:8080/jkweb/
Struts 2 :
changed url pattern for Struts 2 filter from ".action to " /* ". Also
added exclusion filters
to strtus2 for webscoket urls :
<constant name="struts.action.excludePattern" value=".*websocket/.*"/>
Everything seems to be working fine as i am gettting no error anywhere in
apache,tomcat,spring security and Struts2 logs.
However on server side no handlers are called?
Earlier I had faced similar problem but it was because I had put
websocket-api jar in my WEB-INF/lib which was preventing websocket
connection from getting opened. No connection is opened but no handler is
called after that and after some time connection is closed obviously
because of timout I suppose.
Here is my ServerEndPoint class :
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")
public class FileUploadTrackerEndPoint{
private static final Logger logger = LoggerFactory
.getLogger(FileUploadTrackerEndPoint.class);
private static HashMap<String,Session> socketConnectionMap =
new HashMap<String,Session>();
@OnOpen
public void open(Session session) {
Map<String,List<String>> paramMap = session.getRequestParameterMap();
List<String> uniqueTockenValues = paramMap.get("uniqueTocken");
if(uniqueTockenValues != null && uniqueTockenValues.size() > 0){
socketConnectionMap.put(uniqueTockenValues.get(0),session);
}
}
@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());
}
}
}
and my javascript code :
createFileUploadWebSocket : function(){
var that = this;
var uniqueTocken = $("#uniqueTocken").val(),
wsurl =
"ws://phasingapp.com:86/jkweb/websocket/fileuploadtracker?uniqueTocken="+uniqueTocken,
ws;
ws = new WebSocket(wsurl);
ws.onopen = function()
{
alert("opened..") //I get this aler sothis is called
ws.send("test");//however this has not effect ...no
error but server end point is not called
};
ws.onmessage = function (evt)
{
message = evt.data;
if(message == "Done."){
alert("closing..");
ws.close();
$('#progressbar').progressbar('option','value',100);
}
var currentVal =
$('#progressbar').progressbar('option','value');
$('#progressbar').progressbar('option','value',currentVal <= 80
?currentVal+1 : currentVal);
};
ws.onclose = function(evt)
{
// websocket is closed.
alert("Connection is closed..."+evt.code + ":"+evt.reason );
};
ws.onerror = function(evt){
alert("Connection is closed..."+evt.code + ":"+evt.reason );
};
},
Thanks,
Shailesh.