-
Notifications
You must be signed in to change notification settings - Fork 225
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
Add JSON-RPC access to directories and server lists. #3249
base: main
Are you sure you want to change the base?
Conversation
rpc_notification jamulusclient/serverListReceived rpc_method jamulus/pollServerList
Use pollServerList instead of getServerList. (No result returned from the call.) Change "address" to "url"
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.
All in all good. Thanks. See my comments. Also @dtinth could you please have a look at this?
src/clientrpc.cpp
Outdated
QJsonObject objServerInfo{ | ||
{ "url", serverInfo.HostAddr.toString() }, | ||
{ "name", serverInfo.strName }, | ||
{ "countryI", serverInfo.eCountry }, |
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.
Is that consistent how we handle countries elsewhere? Also why is it countryI? Not countryId?
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.
countryId is how country codes are handled elsewhere, e.g. in clientList.
"countryI" is a type - I will fix.
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.
On further consideration (and attempt to use in the field) I think this should be a string holding the country name as text. QLocale is QT specific and JSON-RPC clients may not be QT applications hence this id would be meaningless. I will change it in the PR. I think the country code used in client list should also be changed but that is a breaking change that is not directly related to this PR.
Changes method "jamulus/pollServerList" to "jamulusclient/pollServerList" (for consistency). Changes "url" to "address" in protocol and "server address" in docs. Fixes typo in countryId.
Pushed enhancements in response to PR feedback. |
I have changed from countryID (which is QT specific an not particulary useful to a JSON-RPC client that may not have access to the QLocale class) to country string. I have done this throughout including clientList, etc. for the same reason (it is of more use to a remote client.) I have added connect / disconnect methods but am not triggering a signal to update the GUI. Any help here would be appreciated. I have added a method to provide server ping time and quantity of connected clients. I poll for this from each server after receiving a serverList. I wonder if this is desirable behaviour. (It works well for my use case.) I am aware that I added a function to the client class to expose its ConnLessProtocol. That feels wrong to me but I couldn't see an alternative method to receive CLServerListReceived signal. Maybe someone can validate this. FYI these changes are working well when integrating Jamulus client into Zynthian. |
Adds jamulusclient/connect method. Adds jamulusclient/disconnect method. Adds jamulusclient/serverInfoReceived notification. Return country string rather than (QT specific) country code. Request server info after server list received (to get each server's ping time and num clients).
I think we had a discussion about that in the past. I'm not sure what the consensus was.
Seems not trivial. Does the UI look like it's not connected? I believe there's a Boolean flag to show the faders. But not sure. |
Adds method jamulusclient/recorderState. Changes intrument code to instrument name (remote client may not have access to lookup table). Fixes errors in docs.
Ah. I think the problem was translation. Therefore we used the ID over a string for e.g instruments. Otherwise there's a chance that someone who set the client to non English gets other values than someone who uses the English version |
I could not find this discussion. In a bid to be consistent and provide the most useful information to any client I have changed countryID to country text and instrumentID to instrument text in the JSON-RPC messages. We can't expect all clients to have access to these id/string maps. A client needs to be able to show the correct information. There may be an issue with i18n/l10n in which case we should use an internation standard for country code, e.g. ISO 3166-1. For instrument names we may prefer to change back to jamulus table to allow localisation within client (with associated local tables) although that could be done with strings too, i.e. a default English instrument name with clients able to map to local language.
I think the issue here is that there isn't a signal sent from the client to the client GUI when a connect occurs. There is an assumption that connect will be done only from the connect dialog which explicitly updates the client GUI. I am not sufficiently familiar with QT and jamulus code to best know how to refactor to implement such a signal. I have added |
Please run clang-format on your device or apply the style changes from here: https://github.com/jamulussoftware/jamulus/actions/runs/8416630554/job/23043980690#step:4:1 |
Yes, we need to be consistent and I think the ID was the non optimal agreement. please check what the string is if you change the la gauge to verify it gives back something useful. |
I can't remember the discussion; it was probably while I was inactive for a time. But as mentioned above, using the ID allows for consistency between different language settings. We already require a server operator to look up the correspondence between ID and Country, so they can specify the correct ID. I think so long as we document the list of IDs for Countries (as per Qt5) and Instruments (as per util.cpp), then we can expect a JSON-RPC client developer to have reference to this list and include a suitable mapping in their client. Maybe it would also be useful to output the Country name and Instrument name in any case, according to the current language that is set, but we should still include the ID as well, so the client developer can choose which to use. There's no harm having both. |
On a side note: Having made the above point, I checked my jamulus-php to see what I had done there. I was not including the IDs, so I've just updated it additionally to include the IDs for Country, Instrument and Skill Level. |
I was away for a few days which delayed my response. I just tested and the instrument name (string) is sent in the language selected / configured in the client, e.g. changing from English to Spanish, (after a client restart) the client sends "oyente" instead of "listener". I think this works well. The JSON-RPC client will have the correct instrument name without requring a lookup table (with data redundency and associated risk of error and bloat). The country is always in English, the same as the GUI client so this looks like it might be a compilation issue, i.e. not using the locale / lookup at runtime. So this looks like an issue with the client's core code, not with the JSON-RPC interface. I suggest this be corrected in the client core code so that users see the country name in their native / selected language. We could send both numeric and text representation of the data (country, instrument) as suggested above but this is data redundancy (generally considered a bad thing) within a rather verbose protocol (JSON) so I would prefer not. If the decision makers here decide this is desirable I will change the PR to include the codes too. I recommend keeping the strings as this provides the JSON-RPC client with useful data without the need for manually maintained look-up tables which adds undesirable and unnecessary code. |
I'd argue that the API should not change language. |
If the API uses codes then the map from code to string should also be available via the API, e.g. I could add these extra methods: |
yes. That makes sense. @dtinth any concerns? |
@riban-bw could you please have a look at the code style starting here: https://github.com/jamulussoftware/jamulus/actions/runs/8416630554/job/23043980690?pr=3249#step:4:20 this needs some adjustments. You can most likely copy the patch directly from the output. Otherwise, add the proposed messages. Usually, we'd prefer to have them in a separate PR or at least a clearly separated commit. This PR would then only focus on the initial changes you requested. |
Also to make the JSON-RPC documentation check happy
|
docs/JSON-RPC.md
Outdated
@@ -186,6 +186,22 @@ Results: | |||
| result.clients | array | The client list. See jamulusclient/clientListReceived for the format. | | |||
|
|||
|
|||
### jamulusclient/pollServerList | |||
|
|||
Requests the server list from a specified directory. |
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.
Sorry for my forgetfulness here - you need to update the python script I mentioned below and not edit the file directly
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 have run the script and pushed the changes.
I'm not sure how to do that unfortunately, but I think the code has "emit" somewhere. Otherwise, I'd probably look in the documentation (e.g. https://doc.qt.io/qt-6/signalsandslots.html). Maybe @pljones knows more about the GUI? |
Thanks. There's still a spacing error (remove space before the *) in client.h and a missing one in clientrpc.cpp
is required. |
src/clientrpc.cpp
Outdated
/// @result {string} result.city - The musician’s city. | ||
/// @result {number} result.instrumentId - The musician’s instrument ID (see CInstPictures::GetTable). | ||
/// @result {string} result.instrument - The musician’s instrument. | ||
/// @result {string} result.skillLevel - Your skill level (beginner, intermediate, expert, or null). | ||
pRpcServer->HandleMethod ( "jamulusclient/getChannelInfo", [=] ( const QJsonObject& params, QJsonObject& response ) { | ||
QJsonObject result{ | ||
// TODO: We cannot include "id" here is pClient->ChannelInfo is a CChannelCoreInfo which lacks that field. |
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.
Typo, but not your issue.
// TODO: We cannot include "id" here is pClient->ChannelInfo is a CChannelCoreInfo which lacks that field. | |
// TODO: We cannot include "id" here as pClient->ChannelInfo is a CChannelCoreInfo which lacks that field. |
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.
Fixed in next commit.
docs/JSON-RPC.md
Outdated
@@ -471,3 +526,43 @@ Parameters: | |||
| params | object | No parameters (empty object). | | |||
|
|||
|
|||
### jamulusclient/recorderState | |||
|
|||
Emitted when the client is connected to a server who's recorder state changes. |
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.
So this gets emitted only at connection time, not when the server changes its state as it is connected?
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.
It only gets emitted when the client is connect to a server and that server's recorder state changes. I think the first part is probably redundant -- i.e. it can be assumed that a client won't be informed of state changes to servers to which it isn't connected.
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.
Fixed in next commit.
pRpcServer->HandleMethod ( "jamulusclient/disconnect", [=] ( const QJsonObject& params, QJsonObject& response ) { | ||
if ( pClient->IsRunning() ) | ||
{ | ||
pClient->Stop(); |
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 believe that this should call Disconnect() here instead
Line 1244 in e12cb71
void CClientDlg::Disconnect() |
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.
Nothing should call Dialog methods, except internally. Ever. The Dialog UI might not exist if th RPC interface is in use.
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.
We need to update the UI somehow. -> refactoring needed.
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. If a change to state happens to the Client (CClient
), it should emit an event. The UI (CClientDlg
) can respond to that. But the state should be in the Client itself, not the UI. That way, it's accessible to both UI and RPC-I.
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.
The GUI stuff is a blocker in my opinion, but methods seem to be available.
We should probably check if the gui is running and then call different code.
Otherwise it's the right direction.
Sorry for the delay.
If there's code in the Client Dialog UI that's needed by the RPC interface, it should be moved to the Client itself. There's a lot of code that's been put in the wrong place. The Dialog UI layer should be dumb - just responding to UI events and updating state in the Client (or Server for the Server Dialog UI) - or responding to Client events by updating the UI. It should work stuff out or hold state (for example, like the issue with "Mute" - that's only held in the UI). |
The only thing I can think of is to factor out the actual disconnection process and introduce a GUI method to set the UI to connected and disconnected. |
That's the only correct way to do it with Qt, in my view. The UI is meant to respond to signals - either from the widget set or from CClient. The response to a widget signal should be to update CClient. The response to a CClient signal should be to update the widget layer (including shutting down CClientDlg, if appropriate and not otherwise handled). |
Ok. Then the way to go is to also issue a signal for updating the UI which means that the UI update code needs to be refactored into a new method. |
This PR is to provide improved JSON-RPC interface. I may not be the right person to refactor the core code to improve UI/backend integration with better use of signals. I appreciate and agree with the plan but does that belong in this PR? I feel like there should be a separate bit of work to abstract the core client functionality from the UP to the client code. That may impact (improve) the remote control but feels wrong to bind it to this PR. I am not clear what is outstanding on this PR. I think I have reviewed and fixed all suggestions (thanks) apart from refactoring the client and UI to implement better use of signals. |
The issue is that the UI thing is a blocker for me. |
So we're suggesting:
|
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'm sorry to say that, but in my opinion we need to get the GUI stuff solved. I would suggest to revert the connection and disconnect behavior- which I know is substential out of this PR and get the other changes merged. Then open a new PR with only the connect/disconnect changes. Then we can work on the slot/signal idea there.
Ok. Can we get everything which doesn't break the UI in? |
If this can be split into one PR per change it would probably be easier to get it moving. The changes where there are problems would then not block the changes where there aren't. |
Many of those changes were added in response to reviewer's comments. Do you mean that each reviewer observation should be a seperate PR until the codebase is sufficiently clean to allow the actual PR? Many of the additional changes requested by reviewers relate to historical issues that I was requested to resolve so we do seem to be some way beyond the original PR. Some of these I do not have sufficient understanding of the whole codebase and I may not be the ideal canidate to resolve. |
|
||
### jamulusclient/connect | ||
|
||
Disconnect client from server |
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.
Surely this is
Disconnect client from server | |
Connect from client to server |
Please get rid of the connect/disconnect features then and put them in a separate PR. |
Otherwise: do we find a compromise that the connect/disconnect methods only work headless? |
Ok. Have a look at #3364 If we can get these changes in and probably some refactoring, maybe the GUI issues can be fixed. |
@pljones do you think it makes sense extracting everything except for the connect and disconnect functionality out of this PR and then open a separate PR for just connection an disconnection? Then we do not depend on refactoring the connection/disconnection methods yet. |
I'd rather do no more work on the RPC client that didn't depend on signals from CClient itself -- depending on signals from elsewhere ( |
Short description of changes
Adds JSON-RPC notification of server lists from directories. Allows polling a directory for this info.
CHANGELOG: Added jamulusclient/pollServerList methods and jamulusclient/receivedServerList notification to JSON-RPC interface.
Context: Fixes an issue?
As discussed here, it may be advantageous to increase the control and monitoring provided by the JSON-RPC interface. This provides access to server lists on directories.
Does this change need documentation? What needs to be documented and how?
This PR adds the associated documentation of the new method and notification in the JSON-RPC md page.
Status of this Pull Request
What is missing until this pull request can be merged?
Checklist