[web] Support libevent as WS server instead of libwebsockets#1818
[web] Support libevent as WS server instead of libwebsockets#1818chme merged 6 commits intoowntone:masterfrom
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. |
ejurgensen
left a comment
There was a problem hiding this comment.
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.
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.
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.
I suggest commenting this out, it's usually quite "noisy"
There was a problem hiding this comment.
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
| #include "logger.h" | ||
| #include "commands.h" | ||
| #include "httpd_internal.h" | ||
| #include "websocket_ev.h" |
There was a problem hiding this comment.
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.
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
/wsif 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.