Reputation: 1796
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. Now 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 );
};
},
Upvotes: 0
Views: 649
Reputation: 1796
Again with all other my websocket questions i found the answer in my conffiguration (misconfiguration) itself.
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/
I changed the order of proxypass directives like below:
ProxyPass /jkweb/websocket/ ws://localhost:8080/jkweb/websocket/
ProxyPassReverse /jkweb/websocket/ ws://localhost:8080/jkweb/websocket/
ProxyPass /jkweb !
ProxyPass /jkweb/ !
ProxyPass / http://localhost:8080/jkweb/
ProxyPassReverse / http://localhost:8080/jkweb/
Putting it before the proxypass directive for websocket was causing every request starting with jkweb/ was causing it bypass the proxy.
Upvotes: 1