New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FS#2248 - uhttpd: implement ubus event listener via Server-Sent Event protocol #7133
Comments
jow-: Just implement a long living cgi process and adjust timeout and concurrency values accordingly. I do not understand why modifications to uhttpd itself are required. Please elaborate. |
nicopace: Hi Jo, So, would something like this be possible?
with a publisher like this? if so, will document the usecase so others can benefit. Still, it feels that it could be something that is integrated in the ubus api, as it would complete it by providing the listen and monitor apis that are not available right now. Thanks! |
jow-: The problem I see with listen/monitor APIs is that they can easily use up the entire available connection / request pool in the server. Since there is no builtin timeout by design, a few clients keeping such listen connections open can essentially DoS the entire server. |
nicopace: Having someone connected to the router shouldn't take up much ram/cpu. no buffers need to be kept (each event that comes has to be spitted to the client right away, so no need to buffer it). And as ubus listen/monitor api uses uloop to wait for it, it wouldn't take to much space. Still... if the functionality is available, would be possible to explore this. |
jow-: Well for starters you would need to untangle the max_request, max_connections and timeout variables because right now they apply to both ubus and http (cgi) requests. Furthermore we need to treat ubus monitor and/or listen requests differently than list or call requests because right now ubus calls are strictly limited to the global timeout set through the The SSE protocol looks simple enough so I might consider implementing it but I can't promise any time frame for this at all. |
nicopace: Because the way SSE works, if the session times out, the browser will resume it. so, no timeout/max_connections untanglement needed (at least at the beginning), neither change of global timeout. an mvp would be pretty simple, and then we can walk together once it starts being used. |
nicopace: Hi Jo, I did a small example, put these two files in /www/cgi-bin; ping:
pong:
when i head to router/cgi-bin/ping, it certainly shows 'ping'. i think the uloop loop is not working properly there... any suggestions? ps: no errors in logread either... |
nicopace: Ok, did another test with os.popen and it works.
#!/usr/bin/lua
|
nicopace: So, it worked! This is what goes on /www/cgi-bin/ubuslisten
and this on /www/ubuslisten.html
<script>
var source = new EventSource("/cgi-bin/ubuslisten");
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
</script>
two drawbacks of this implementation:
|
Seems like it's implemented? https://lists.openwrt.org/pipermail/openwrt-devel/2020-September/031396.html |
nicopace:
Usecase:
As a web developer I would benefit from having the possibility to send events from the server to the browser so the browser can react to it dynamically.
The proposed implementation is the leanest possible.
A SSE ([[https://www.w3.org/TR/eventsource/|Server-Sent Event]]) is a simple protocol on top of basic http polling to send messages from the http server to the browser for the purpose of instant notifications.
It comes implemented in all major browsers, including [[https://streamdata.io/blog/server-sent-events/|mobile]].
If paired with
ubus listen
orubus monitor
, a seamless integration with the ubus pipeline could be implemented.We tried to implement it by adding an option in [[https://git.openwrt.org/?p=project/uhttpd.git;a=blob;f=ubus.c;hb=HEAD#l530|this line of code]] but got stuck in our lack of corutine mechanisms and how uhttpd works.
The difference with the call and list options is that this one should be long-lived and progressive, preventing the dreaded polling from the web (also, better us of resources, more elegant implementation, etc).
As an example, a very basic implementation of a SSE server in php:
An example of a very basic implementation of a SSE client in HTML:
<script> var source = new EventSource("demo_sse.php"); source.onmessage = function(event) { document.getElementById("result").innerHTML += event.data + "
"; }; </script>
The text was updated successfully, but these errors were encountered: