Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Vaadin Push work through Apache HTTP server?

I'm trying to get Vaadin 7.1.5 Push to work on Apache Tomcat 7.0.42 + Apache HTTP server (2.2.14 with mod_proxy_wstunnel).

The Vaadin application and push with WebSocket works fine when I access Tomcat directly (ie. http://mydomain:8080/myapp). The problem arises when I try to access it by using the Apache modules mod_proxy & mod_proxy_wstunnel. What happens is that the application hangs, the loading indicator gets red and I get this error in the push request in the browser console:

HTTP Status 501 - Websocket protocol not supported
type Status report
message Websocket protocol not supported
description The server does not support the functionality needed to fulfill this request.

Apache Tomcat/7.0.42

Before Push was needed, I used mod_jk to forward requests from http://mydomain/myapp to http://mydomain:8080/myapp. Apparenly mod_jk doesn't support WebSocket so I chose to use ProxyPass directive. Here's my Apache config:

ProxyPass               /myapp/PUSH/ ws://localhost:8080/myapp/PUSH/
ProxyPassReverse        /myapp/PUSH/ ws://localhost:8080/myapp/PUSH/

ProxyPass               /myapp/VAADIN/ http://localhost:8080/myapp/VAADIN/
ProxyPassReverse        /myapp/VAADIN/ http://localhost:8080/myapp/VAADIN/
ProxyPass               /myapp http://localhost:8080/myapp
ProxyPassReverse        /myapp http://localhost:8080/myapp

I was suspecting that mod_proxy_wstunnel was to blame, but apparently it works fine when I proxy http://echo.websocket.org. I found out that the 501 error is thrown by Atmosphere, but I don't have a clue how to debug it. If I remove the ws proxy (so the push uses HTTP instead of WS), I get an instant "Session expired" error.

Does anyone know how to properly proxy push requests from Apache HTTP server to Apache Tomcat?

like image 853
miq Avatar asked Sep 20 '13 13:09

miq


1 Answers

I solved this by making sure the path of ProxyPass (and ProxyPassReverse) is identical to the context of the application and creating a new NIO connector in tomcat's server.xml config:

<Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol"
           connectionTimeout="20000"
           redirectPort="8443"
           proxyName="mydomain"
           proxyPort="80" />

I'm quite sure there is a way to use a path that is different from the application context, but this works for me.

UPDATE: Note that this solution doesn't work with browsers that don't support websocket (eg. IE <= 9). I suspect it has something to do with the HTTP streaming as fallback method..

like image 55
miq Avatar answered Oct 04 '22 23:10

miq