Copyright © https://mongoose-os.com

Mongoose OS Forum

frame

BeagleBone, Apache and Mongoose C++

Hi Everyone,

I'm working on a C++ application running on a BeagleBone Black (Linux beaglebone 4.4.91-ti-r133 #1 SMP Tue Oct 10 05:18:08 UTC 2017 armv7l GNU/Linux). The purpose of this app is controlling model railroads according to the NMRA DCC standards. Besides other protocols, I try to let the users control the application through a website. Therefor I installed apache on the BeagleBone so as it could serve web page requests via port 80. I'm able to write php server-site and html/javascript on the client site.

AFAIK, WebSockets also use port 80 on the server. I digged into the apache documentation and setup a wstunnel. I enabled ws-tunneling by
# a2enmod proxy-wstunnel
and edited /etc/apache2/sites-enabled/000-default.conf to (snippet)

    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    ProxyRequests Off
    ProxyPass "/ws/" "ws://localhost:9030/"
    ProxyPassReverse "/ws/" "ws://localhosr:9030/"
    ProxyPass "/wss/" "wss://localhost:9030/"
    ProxyPassReverse "/wss/" "wss://localhost:9030/"

Am I correct by assuming that this setup allows every websocket to be redirected to port 9030 on the same machine ?

I wrote this code to test the websocket (WebSocketTest.php)

To test my mongoose application I wrote (main.cpp):

However, I'm not able to get any response (ev_handler is never called...)

Since I'm new to websocket programming, it is quiet possible that this all makes no sense. But this must be possible anyway.

Any suggestions are very welcome !

Thanks in advance for your feedback.

Regards,
Paul

Comments

  • I"m not following exactly what you are trying to do, but I think it is similar to what I have done.
    I see you are using the Mongoose Networking library in the "raw" form. Well, "raw" meaning relative to Mongoose-OS.
    Mongoose-OS seems to take the Mongoose Networking library up another level of abstraction.

    Have a look at my project, and I think you will see that the Mongoose-OS way of doing things is simpler:

    https://github.com/Greg-R/websocket_send_periodic_temp

    This project is an http-server with websocket, and I think it has the features you require.

    I am using the http-server library. The two primary functions required are mgos_get_sys_http_server() and mgos_register_http_endpoint()
    and can be seen in the file src/main.c.

    There are some unused events left in the ev_handler function for illustration purposes.

    Note the header file mgos_http_server.h. This may no longer be required. I will do a test of that soon and commit a change if this is the case.
    Please note I have documented the project in the PDF file:

    doc/esp32websocket.pdf

    I am going up the learning curve too, and I also did some programming in the Beaglebones.

    Regards,
    Greg

    Thanked by 1Paul
  • Tried to build without the mgos_http_server.h header file. No go with latest mos build tool! The header include stays.

  • Hi Greg,

    Thanks for your reply ! I'm browsing your project, very nice.

    AFAICS, the only functionality in your project is updating webpages with new info, right? My goal is to embed a websocket server into an existing C/C++ application. This application is responsible for very different tasks (communication layers, user managment, device managment etc.) and is multi-threaded. I'm writing a web interface now. This website is hosted by an apache server running on the same beaglebone. The problem now is that the web-pages needs to be updated if some/any of the devices in the C/C++ application changes state. My idea is to do this with the use of websockets and (maybe) JSON.

    So, again, AFAIK, this is another approach than you did. Is it possible to implement mos in a thread running inside my C/C++ app? Is that the recommended way to go?

    regards,
    Paul.

  • OK, now I understand, you are going to use Mongoose Networking library on the Beaglebone (I think)!
    I was thinking the Beaglebone would be some sort of master, with a Mongoose based slave device, perhaps embedded in the locomotive.

    Is the C++ application a bare application, or running LInux?

    So if you are running LInux on a Beaglebone, there would be massive networking capability available in numerous libraries without having to add in Mongoose.
    I could see how it might be required if you were writing a bare C++ application. But then you would miss enormous power of Linux networking capability on
    a machine which is totally capable of this.

    You are correct my little Mongoose-OS project is uni-directional, from ESP32 server to Web page via Websocket.
    I did a two-way Websocket project on a Beaglebone:

    https://github.com/Greg-R/irrigate-control

    This is based on Node.js. Node.js is strongly recommended for this sort of thing. You would need to "proxy" the Node.js server through Apache for security reasons.
    Also, you should be able to call Node.js from C++ and vice versa.

    My understanding of Mongoose is that it is targeted at sort-of "mid-range" devices. Somewhere between an Arduino and a Beaglebone would be a crude way to state this.
    I think if you are on the Beaglebone, you have access to way more libraries and power for networking.

  • PaulPaul Belgium
    edited November 2017

    Greg,

    The C++ application is running on the BeagleBone (running Debian). The apache webserver is also running on the beaglebone and serves web-pages using php (server-side) and javascript (client-side). The problem is, simply stated, I need a 'channel' to comunicate between the client-site (web browsing the pages) and the different C++ objects living inside the C++ application. I'm trying to accomplish this by integrating mongoose into the C++ part, letting the C++ application act as a websocket server with internal access to the class instances.

    ATM, I have configured the apache server so that it forwards websocks to port 9030. My mongoose testapplication (C++) receives a first mesage (the ev_handler function is called with ev == MG_EV_RECV). The received message is :

    GET / HTTP/1.1
    Host: 127.0.0.1:9030
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
    Accept-Language: en-GB,en;q=0.5
    Accept-Encoding: gzip, deflate
    Sec-WebSocket-Version: 13
    Origin: http://192.168.1.52
    Sec-WebSocket-Extensions: permessage-deflate
    Sec-WebSocket-Key: QViy+9zW+Wi0lvHD7zrOBQ==
    Pragma: no-cache
    Cache-Control: no-cache
    X-Forwarded-For: 192.168.1.13
    X-Forwarded-Host: 192.168.1.52
    X-Forwarded-Server: beaglebone.localdomain
    Upgrade: WebSocket
    Connection: Upgrade

    I think I've to figure out how to respond to this... (doing something with Sec-WebSocket-Key to confirm the connection, maybe... ??)

    For the moment, I'm only exploring the possibilities/feasibility of this idea. Any suggestions about other technologies/methods/practices are very welcome !

    greets,
    Paul.

  • This looks like the prelude to the Websocket "handshake" process. There is a standard for this, and well above my amateur level!
    I believe Sergey has commented on this, and this is why you have the for(::) loop and the mg_mgr_poll(). It cranks through the multi-step process to establish the Websocket.
    Mongoose-OS seems to hide these details, but then only deployed on certain devices, so in your case it would appear you must deal with it.

    It would be interesting to see Mongoose Networking go on the Beaglebone; I have been monitoring the Google Group for a couple of years, and I don't recall mention of it.

  • This looks like the prelude to the Websocket "handshake" process.

    I think it is. Have to delve into the specifications to figure out... that's for tomorow, it's 00:00 AM here....

    Anyhow, if I make any progress in this adventure, mongoose wil be integrated into my main project. You can take a peak at my github account when things evolve positive :wink:

    Regards,
    Paul

  • I see you've done some work with PRU + RemoteProc. I spent a bit of time experimenting with the same combination. Now that I have spent time with ESP32 and Mongoose-OS, the PRU seems too constrained. If you could only put an RTOS on it, maybe, but otherwise if I do another project with Linux + real time it will be with a Linux embedded system + an ESP32 connected via SPI bus. I would really like to hear about what others are thinking.

  • PaulPaul Belgium
    edited November 2017

    Finally, I got this working :

    However, since all ws requests are forwarded by apache, I'm not able to distinguish the sockets by their real IP... How can I solve this? In the remote shell console (right-bottom in image), the first message is send from firefox under debian (in VirtualBox), the second is send from FireFox under Win10. The console output shows for both connections 127.0.0.1, which refers to the localhost ON THE BEAGLEBONE.

  • Congratulations on Websocketing!

    I've done almost zero with Apache, but I need to learn if I ever put any web-facing devices online.
    Looks like there are options for Apache which will get the client IP forwarded in a special header.

    https://docs.alertlogic.com/userGuides/web-security-manager-premier-preserve-IP-address.htm

    https://httpd.apache.org/docs/2.4/mod/mod_proxy.html

    Interesting comments about the "reverse proxy":

    https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers

  • I've got 2 books devoted to Websocket. There is only brief mention of Apache in one of them. They provide this link:

    https://stackoverflow.com/questions/27526281/websockets-and-apache-proxy-how-to-configure-mod-proxy-wstunnel

    This is about an Apache module proxy_wstunnel. A lot of the comments are in regards to Node.js.
    The "reverse proxy" is mentioned.

Sign In or Register to comment.