Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lighttpd with webSocket

Tags:

lighttpd

I am trying to make a simple webapp which uses websocket for communication with the lighttpd server. Unfortunately my setup does not work and i do not know why. Search in the internet does not offer clear example how to use mod_wstunnel( May be someone has experience with lighttpd. Below you can find my sandbox:

lighttpd.conf

server.modules += ("mod_wstunnel", "mod_setenv")
server.indexfiles = ("index.html")
server.document-root = "/var/www/html/websocket"

$HTTP["url"] =~ "^/websockify" {
    wstunnel.server = ( "" => ( ( "host" => "127.0.0.1", "port" => "5900" ) ) )
    wstunnel.frame-type = "binary" 
    server.stream-request-body  = 2
    server.stream-response-body = 2
}

index.html

<h1>Real Time Messaging</h1>
<pre id="messages" style="height: 400px; overflow: scroll"></pre>
<input type="text" id="messageBox" placeholder="Type your message here" style="display: block; width: 100%; margin-bottom: 10px; padding: 10px;" />
<button id="send" title="Send Message!" style="width: 100%; height: 30px;">Send Message</button>

<script>
  (function() {
    const sendBtn = document.querySelector('#send');
    const messages = document.querySelector('#messages');
    const messageBox = document.querySelector('#messageBox');

    let ws;

    function showMessage(message) {
      messages.textContent += `\n\n${message}`;
      messages.scrollTop = messages.scrollHeight;
      messageBox.value = '';
    }

    function init() {
      if (ws) {
        ws.onerror = ws.onopen = ws.onclose = null;
        ws.close();
      }

      ws = new WebSocket("ws://127.0.0.1:5900/websockify")
      ws.onopen = () => {
        console.log('Connection opened!');
      }
      ws.onmessage = ({ data }) => showMessage(data);
      ws.onclose = function() {
        ws = null;
      }
    }

    sendBtn.onclick = function() {
      if (!ws) {
        showMessage("No WebSocket connection :(");
        return ;
      }

      ws.send(messageBox.value);
      showMessage(messageBox.value);
    }

    init();
  })();
</script>

Thanks in advance for the help.

like image 975
user1578679 Avatar asked Nov 19 '25 00:11

user1578679


1 Answers

I've been using the boost::beast c++ library to do something like this ... but the idea is the same for any other language/library.

Most of the available ws libraries (c++ or other) are thought as stand-alone websocket servers, designed to stand by themselves. To make them work as a lighttpd backend, the web server needs to proxy the websocket messages, making the libraries to believe they're receiving a direct client feed. Think of your server as communicating with lighttpd like a cgi app ... not exactly, but that's the idea.

Like gstrauss has said, lighttpd does this using mod_proxy:

server.modules   += ( "mod_proxy" )

$HTTP["url"] =~ "^/wsck" {
    proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => "6000" ) ) )
    proxy.header = ( "upgrade" => "enable" )
}

From Boost::Beast pick a server example (other languages should have similar libraries):

https://www.boost.org/doc/libs/1_75_0/libs/beast/doc/html/beast/examples.html

Compile and leave it running in the background. Don't forget the ports between lighttpd.config and the websocket daemon must match!!!

From javascript the websocket is created by:

ws = new WebSocket("ws://yourServer.xyz/wsck");

All the other code can remain the same ... I haven't checked yours ;-)

Plase note that no port number is not used here. We are talking directly to lighttpd, which proxies the request to the backend running server (which has port 6000 open).

Hope it helps!

like image 166
Francisco Avatar answered Nov 22 '25 05:11

Francisco