Setting up a websocket on Apache? Setting up a websocket on Apache? apache apache

Setting up a websocket on Apache?


The new version 2.4 of Apache HTTP Server has a module called mod_proxy_wstunnel which is a websocket proxy.

http://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html


I can't answer all questions, but I will do my best.

As you already know, WS is only a persistent full-duplex TCP connection with framed messages where the initial handshaking is HTTP-like. You need some server that's listening for incoming WS requests and that binds a handler to them.

Now it might be possible with Apache HTTP Server, and I've seen some examples, but there's no official support and it gets complicated. What would Apache do? Where would be your handler? There's a module that forwards incoming WS requests to an external shared library, but this is not necessary with the other great tools to work with WS.

WS server trends now include: Autobahn (Python) and Socket.IO (Node.js = JavaScript on the server). The latter also supports other hackish "persistent" connections like long polling and all the COMET stuff. There are other little known WS server frameworks like Ratchet (PHP, if you're only familiar with that).

In any case, you will need to listen on a port, and of course that port cannot be the same as the Apache HTTP Server already running on your machine (default = 80). You could use something like 8080, but even if this particular one is a popular choice, some firewalls might still block it since it's not supposed to be Web traffic. This is why many people choose 443, which is the HTTP Secure port that, for obvious reasons, firewalls do not block. If you're not using SSL, you can use 80 for HTTP and 443 for WS. The WS server doesn't need to be secure; we're just using the port.

Edit: According to Iharob Al Asimi, the previous paragraph is wrong. I have no time to investigate this, so please see his work for more details.

About the protocol, as Wikipedia shows, it looks like this:

Client sends:

GET /mychat HTTP/1.1Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==Sec-WebSocket-Protocol: chatSec-WebSocket-Version: 13Origin: http://example.com

Server replies:

HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=Sec-WebSocket-Protocol: chat

and keeps the connection alive. If you can implement this handshaking and the basic message framing (encapsulating each message with a small header describing it), then you can use any client-side language you want. JavaScript is only used in Web browsers because it's built-in.

As you can see, the default "request method" is an initial HTTP GET, although this is not really HTTP and looses everything in common with HTTP after this handshaking. I guess servers that do not support

Upgrade: websocketConnection: Upgrade

will reply with an error or with a page content.


I struggled to understand the proxy settings for websockets for https therefore let me put clarity here what i realized.

First you need to enable proxy and proxy_wstunnel apache modules and the apache configuration file will look like this.

<IfModule mod_ssl.c>    <VirtualHost _default_:443>      ServerName www.example.com        ServerAdmin webmaster@localhost        DocumentRoot /var/www/your_project_public_folder      SSLEngine on      SSLCertificateFile    /etc/ssl/certs/path_to_your_ssl_certificate      SSLCertificateKeyFile /etc/ssl/private/path_to_your_ssl_key      <Directory /var/www/your_project_public_folder>              Options Indexes FollowSymLinks              AllowOverride All              Require all granted              php_flag display_errors On      </Directory>      ProxyRequests Off       ProxyPass /wss/  ws://example.com:port_no        ErrorLog ${APACHE_LOG_DIR}/error.log        CustomLog ${APACHE_LOG_DIR}/access.log combined    </VirtualHost></IfModule>

in your frontend application use the url "wss://example.com/wss/" this is very important mostly if you are stuck with websockets you might be making mistake in the front end url. You probably putting url wrongly like below.

wss://example.com:8080/wss/ -> port no should not be mentionedws://example.com/wss/ -> url should start with wss only.wss://example.com/wss -> url should end with / -> most important

also interesting part is the last /wss/ is same as proxypass value if you writing proxypass /ws/ then in the front end you should write /ws/ in the end of url.