Use relative path for websocket
If the mopidy server is mounted in a subdirectory via a reverse proxy (e.g., https://domain/mydir, such that apps are available under https://domain/mydir/app), then the default websocket url in https://github.com/mopidy/mopidy.js/blob/master/src/mopidy.js#L65 points to the wrong location. Since the code already uses browserify (yey!), a solution is to use url.resolve() in order to determine the path:
var url = require("url");
var path = url.resolve(
(typeof document !== "undefined" && document.location.pathname) || "/",
"../mopidy/ws"
);
and then
settings.webSocketUrl = settings.webSocketUrl ||
protocol + currentHost + path;
In my setup, mopidy is mounted in a subdirectory via nginx and it took me a while to figure out why moped wasn't able to connect to the websocket. The above change would make it work without any further configuration.
What do you think?
Doesn't this assume that the web client is running at /foo/ and doesn't use e.g. the history API to have more meaningful URLs like /foo/artist/ABBA?
Good observation, that's true. Summary:
- current situation: URLs like
/foo/artist/ABBAwork if mopidy is mounted at the webserver's root. - above proposal: web clients running at
/foowork if mopidy is mounted at a custom URLs like/mymusic, i.e. the web client runs at/mymusic/foo.
In the first situation, the web client is aware of the fact that it is serving a page from a subdirectory of the web client and could adjust the websocket URL.
It's difficult for me to estimate the consequences in this project. :) Are there web clients that use the history API?
I don't know, there is quite a few clients and I haven't looked closely at any of them. If there isn't, it still something I'd really like clients to do so back/forward etc works properly, so I don't want to do anything that makes it harder on clients using the History API.
Some thoughts:
- if the default websocket URL remains unchanged, then the user of the software (i.e., the person who's installing it) will have to modify the source code of the web client if it is made available under a subdirectory and the web client does not expose the websocket URL as an configurable option to the user.
- if the default websocket URL is relative to the web client, then the developer of the web client has to take care that the proper websocket URL is used if the client uses subdirectories internally.
Personally, I was surprised how difficult it is to let mopidy run in a subdirectory. For example, the musicbox_webclient has hard-coded absolute URLs all over the place and isn't usable at all since you can't configure it. Moped did a much better job – only the websocket URL was preventing it from running out of the box.
Hey, sorry for the thread-necromancy, but I see this still hasn't been resolved. Is there any plan/intent to fix this eventually?
I'm trying to set up a system with multiple mopidy-instances/streams running at the same time, and it seems kinda silly to use multiple ports (or virtual hostnames) just for HTTP when they could all just be separate paths under the one http://music..../ endpoint.
I was able to trick Iris into supporting similar enough by setting the port to something like "80/ch02" which hopefully won't be patched out later with assert type(port) == int.
This is likely good enough for me for, but if something upstream in the code managed by the mopidy team could set the precedent for this kind of feature that'd be great.