-
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
JSON-RPC interface to control client and server #1975
Conversation
From the discussion, @ann0see suggested pinging:
I would appreciate your feedback on this idea and how it’s implemented. |
Looks nicely done. In the longer term, if greater separation between clientui and client and between serverui and server can be achieved, with both having clearer interfaces, this concept can be extended easily enough to take advantage of it. I'll have a good read through later. |
Looks good to me. I think using MQTT may be more convenient on the server, with more natural support for notifications from jamulus to client code, but in the end the functionality would be very similar. On jamulus client RPC seems preferable. |
OK, the main thing I'd like is for it to be possible for any method that can change state to be protected, so someone could expose those methods that retrieve state whilst not allowing control of a 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.
@pljones Thanks for the thorough review. I will address them in code later, but here are replies to your comments.
In particular, this one is about endpoint protection.
@cdmahoney So you'd suggest having both. Maybe you and @dtinth could agree on implementing one on the client and the other one server side? I'd leave the decision up to you but please keep in mind that duplicate work or even implementing two similar features is counter productive. Edit: Could someone please also have a look at #1990 and compare & discuss the differences? Edit: from the discussion Peter was neither happy with Mqtt and the file approach: #1847 (reply in thread) Edit: To all contributors: Even if your suggestion is not merged/accepted, it will have had a huge impact on the one which did get included since your ideas probably got integrated. It's better to agree on one solution and improve this one than merging none or not improving the accepted one. |
One of the best bits here is that it connects to client.cpp and server.cpp, exposing their existing behaviour in a clean manner without being invasive. |
@pljones Thanks, I have addressed your comments in the code. I will leave it to you to mark them as resolved. |
@ann0see I just looked at Rob-NY@b3dac8a. @Rob-NY’s implementation uses the same CL (connectionless) UDP-based protocol that is used in Jamulus, which is more lightweight, allows more code reuse, and should be lighter, in terms of load. As for my implementation, I focused on ease of integration, so I opted to make the protocol strictly based on plaintext and JSON. This makes it more heavyweight (uses TCP and does more work to parse and serialize JSON) although I believe performance impact is negligible. Note that the current implementation of JSON-RPC does not yet implement recording controls (start/stop/get status) as I currently do not use the recording feature in Jamulus. Should JSON-RPC proposal be accepted, I suggest implementing recording feature on top of this PR, in order to keep this PR small. My implementation in this PR is mostly focused on automating the client, as I needed that for jamcaster (a tool that streams a Jamulus room to Icecast, YouTube or Facebook from a headless Linux server, see demo). |
Thanks for the explanation. Personally, I think although your approach might violate https://github.com/jamulussoftware/jamulus/blob/master/CONTRIBUTING.md#keep-it-simple-and-stupid-and-do-one-thing-and-do-it-well it is expandable which will make following additions easier. I'd vote for your approach.
|
Addressed all the comments above, thank you @pljones. |
My fork and this PR has diverged quite significantly now that my current supporting scripts are now incompatible (as a result, my servers are stuck at version 3.8.1 for the time being), so I’d also prefer option 1. Once this is merged, I plan to rebase my fork on top of it (i.e. reapply all of my changes again but on top of latest master), so that I can upgrade all my servers to be based on the new JSON-RPC interface and provide additional testing. (Since the codebase has diverged, it is now no longer practical for me to test this PR on my fleet of servers; I’d rather wait for this to get merged first so I have a more stable base commit to rebase on top of.) Therefore I’d prefer to be more aligned with trunk-based development where it’s ok to ship incomplete/unstable features behind feature flags. Given that the JSON-RPC code is “latent” (has no runtime effect) until explicitly enabled, and that this feature is clearly marked as experimental1, IMO it is in a mergeable state.
My main use case for implement changeable skillLevel was to achieve blinking color for the streamer client2 😂 Footnotes
|
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.
Approving on the basis that:
- I have tested it a few days ago
- As dtinth said it is not critical
- We are planning (hopefully!!!) to extend and improve this
- There was an excessive descussion and it is being tried on a real server.
I think the website is being developed in a comparable method - but it created and creats a lot of confusion... |
Well there you go! It never occurred to me that the reason for using it could be anything other than actual skill level! Very creative... |
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 think this is close enough to merge now. Let's get it in and then address improvements incrementally.
Can or can’t we squash merge this? |
Yes, will do, that was the plan anyway (I want it to make it three commits though). |
I was going to say if you want to have some nicer to read commits... but didn't want to suggest the extra work. :) |
Co-authored-by: ann0see <20726856+ann0see@users.noreply.github.com> Co-authored-by: Christian Hoffmann <mail@hoffmann-christian.info>
Co-authored-by: Christian Hoffmann <mail@hoffmann-christian.info>
I've rebased and polished the history. I've confirmed via PR can be merged on CI green. |
A nightly should be tagged (and maybe shortly announced in GH discussions) after this has been merged. |
@dtinth I just saw that you are not listed at https://github.com/jamulussoftware/jamulus/blob/master/src/util.cpp#L494 I neither wanted to add you with your full name without your consent nor did I want to delay the PR, but feel free to send a quick PR to add yourself. Thanks again for all your hard work on this big feature/PR! :) |
@hoffie Finally~ 🎉 I will add it later tonight, thank you for mentioning that. And thanks everyone involved for helping with pushing this PR to completion. I’ll test it on some of my servers soon. 🙏 🙏 |
Per comment on jamulussoftware#1975 (comment)
Per comment on jamulussoftware#1975 (comment)
Removing the "needs documentation" label since documentation should be discussed in jamulussoftware/jamuluswebsite#717 |
Short description of changes
Allow Jamulus client and server to be programmatically controlled through a JSON-RPC-based protocol.
Context: Fixes an issue?
This PR addresses the following items:
jamulusserver/setWelcomeMessage
to dynamically change welcome message.jamulusserver/getConnectedClients
to get clients connected w/ IP info.jamulusserver/getServerInfo
to get server statusDoes this change need documentation? What needs to be documented and how?
--jsonrpcport <port>
Status of this Pull Request
I did this PR mainly to solve my own issues, so I see this more like an RFC with a working implementation. So PR status is more like a proof of concept, although I am already using it in my own systems.Also I am C++ noob, so there may be major issues with the code, esp with memory management.Update: All PR comments have been address and all checks have passed, I believe the PR is in a mergeable state.
What is missing until this pull request can be merged?
master
branch (right now it is on top ofr3_8_0
).Checklist
Background
I would like to programmatically control Jamulus server and client. My use cases include:
I have seen the proposal to add MQTT-based interface to Jamulus server. I prefer RPC-style messaging more and also would like to control the client programmatically. So I played around with Jamulus source code and came up with this.
High level design
This PR adds a
--jsonrpcport
CLI flag.It introduces three main classes:
CRpcServer
, a generic JSON-RPC server built on top ofQTcpServer
.CClientRpc
, an implementation of an RPC interface for the Jamulus client.CServerRpc
, an implementation of an RPC interface for the Jamulus server.Client methods (
-->
) and broadcast notifications (<--
) implemented:--> jamulusclient/getClientInfo {}
--> jamulusclient/getChannelInfo {}
--> jamulusclient/getClientList {}
--> jamulusclient/setName { name }
--> jamulusclient/setSkillLevel { skillLevel }
--> jamulusclient/sendChatText { message }
<-- jamulusclient/chatTextReceived { text }
<-- jamulusclient/connected { id }
<-- jamulusclient/clientListReceived { clients }
<-- jamulusclient/disconnected {}
<-- jamulusclient/channelLevelListReceived { channelLevelList }
Server methods (
-->
) and broadcast notifications (<--
) implemented:--> jamulusserver/getServerInfo {}
--> jamulusserver/getConnectedClients {}
--> jamulusserver/setServerName { serverName }
--> jamulusserver/setWelcomeMessage { welcomeMessage }
How to use the JSON RPC server
On Unix systems, you can use netcat to talk to the server:
Once connected, send a request on a single line, then the response will come back on a single line. In the example below, the first line is the request, and the second line is the response.
Node.js, jayson can be used to talk to the server: