-
Notifications
You must be signed in to change notification settings - Fork 244
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
[web] Support libevent as WS server instead of libwebsockets #1818
Conversation
Sounds really promising. Too bad that the libevent team is slow at releasing versions of their library; last commit was last year. |
Yes, more frequent releases of libevent would be nice. Especially because it also takes quite a long time until all the distros pick up the new release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a few comments and suggestions. I think it should work with the multithreaded http server, at least as long as THREADPOOL_NTHREADS is 1, because then there is still only one httpd thread and one evhttp instance.
src/websocket_ev.c
Outdated
struct client *client = NULL; | ||
char *reply = NULL; | ||
|
||
for (client = clients; client; client = clients->next) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look thread safe to me since clients is a global? And is evws_send_text safe to call with ->evws, which looks like it belongs to the httpd thread's evhttp?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thread safety is an issue. I reworked it. The listener callback now triggers a command executed in the httpd thread (hope I did it correctly). Required a bit of additional refactoring of the listener call back function.
The listener now supports passing an opaque pointer (context) when adding a listener. This pointer is then passed to each notify callback invocation.
src/websocket_ev.c
Outdated
return -1; | ||
} | ||
|
||
DPRINTF(E_DBG, L_WEB, "notify callback request: %s\n", json_object_to_json_string(request)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest commenting this out, it's usually quite "noisy"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This log is only written once per websocket connection. It should not be that noisy.
I have reduced the log level for the "notify callback event received" log message to "spam". That seems to me noisier and not the helpful.
src/httpd_libevhttp.c
Outdated
@@ -38,6 +38,7 @@ | |||
#include "logger.h" | |||
#include "commands.h" | |||
#include "httpd_internal.h" | |||
#include "websocket_ev.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
websocket_ev.c isn't that much code, and since it's tied to libevent's evhttp and not called from anywhere else, you could just add it here in httpd_libevent.c?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mmh .. generally I am not a fan of huge files, but given that with the changes to make it thread safe it is more tightly coupled with httpd_libevent.c
, I moved the code now into httpd_libevent.c
.
If libevent >= 2.2 is detected during configure and "websocket_port" == 0 in the config file, the libwebsocket implementation is disabled and instead the libevent http server offers the websocket connection. The connection to the websocket is then done with the path "/ws".
61d6945
to
f2e4819
Compare
Thanks for taking the time to review this change and apologies for the lack of response from me. I finally got around and rebased the changes on top of I'll test this more over the coming weeks to see if it is stable (at least for my set up). |
Excellent, you are welcome to merge it when you think it's ready. Looking forward to using this as the default, but I guess we have to wait for a libevent release. It's fine to keep the version check of libevent instead of feature check, and I agree the map can wait. |
I have merged it now. It is working stable for me for quite some time now (with libevent build from git). Too bad, there is no progress on a new libevent release though. And given how long Debian release cycles are, it will probably take around three years, until this will be usable on Debian distros ... |
The next planned minor release 2.2 of libevent will have support for running a websocket server. I thought, I give it a try and see if it works in OwnTone and check if it is something worth adding :-)
The changes in this PR add a libevent based websocket server, that accepts connections under the path
/ws
(and the same port as the web interface).If libevent >= 2.2 is detected during configure and "websocket_port" == 0 in the config file, the libwebsocket implementation is disabled and instead the libevent websocket server is active.
The web interface was updated to attempt a WS connection to
/ws
if websocket_port == 0.The advantages in using libevent are - if it proves to be reliable - that the libwebsocket dependency could be removed. Additionally, only having one port for the web interface, will make it easier to use a reverse proxy with OwnTone (especially if the reverse proxy is running on the same host).
I did some short tests, and it seems to be working fine, but more tests are required.
I tested it locally and by building an OwnTone container with libevent from git-master (https://github.com/chme/owntone-container/tree/feat/libevent-git). Also I am unsure how it will work with the multi threading support of the http server in OwnTone.
Currently only an alpha release of libevent 2.2 is available (https://github.com/libevent/libevent/releases/tag/release-2.2.1-alpha) . Note, that the libevent 2.2.1 alpha release contains a bug that prevents ws connections from Firefox (Chrome is working fine). The bug is already fixed in the master branch of libevent.