Add JSON-RPC methods to connect, disconnect and query connection state#3806
Add JSON-RPC methods to connect, disconnect and query connection state#3806mcfnord wants to merge 6 commits into
Conversation
This is an extract from jamulussoftware#2550 Co-authored-by: ann0see <20726856+ann0see@users.noreply.github.com>
Introduce EConnectionState (disconnected / connecting / connected) owned by CClient as the single source of truth. A connection is 'requested' when the audio stream starts (CS_CONNECTING) and 'established' once the server assigns our channel ID (CS_CONNECTED). Every transition emits ConnectionStateChanged. Rename the Connected(name) signal emitted from Start() to Connecting(name), since at that point the connection is only requested, not established. CClient::Connect() now terminates any current connection first, so connecting while connected behaves as a reconnect. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
965d397 to
cecdea1
Compare
|
Rebased this branch onto #3815 and added an optional When The stack is now #3805 → #3815 ( Relates to jamulussoftware/jamuluswebsite#1122. |
- SIGTERM/SIGINT: route through Disconnect() instead of a raw Stop(), and guard Disconnect() on the connection state rather than IsRunning() (which tracks the audio device). IsRunning() is false while connecting and in headless mode, so the old guard could skip notifying the server on shutdown; the raw Stop() worked around that but also fired a spurious disconnect when idle. Now the server is notified iff a connection is pending or established, via the single Disconnect() path. - Move EConnectionState from util.h to client.h (it is client specific). - Add a doc-comment to SetConnectionState; reword two member comments. Addresses review feedback on jamulussoftware#3805. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-c / --connect connects straight to the given address and, unlike selecting a server from the GUI directory list, never asks a directory to open the target's firewall. Servers behind a cloud firewall/NAT that the GUI reaches fine are therefore silently unreachable via -c. Give CClient::Connect an optional directory argument: when set it sends a CLM_REQ_SERVER_LIST to that directory (which makes the directory poke its registered servers towards our socket -- the same UDP hole punch the GUI relies on), waits HOLE_PUNCH_CONNECT_DELAY_MS, then connects. The server address is used verbatim and need not be listed by the directory. Expose it on the command line as --connectdirectory <host:port>, wired through both the GUI and headless connect-on-startup paths in main.cpp. Relates to jamulussoftware/jamuluswebsite#1122 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New methods: jamulusclient/connect, jamulusclient/disconnect and jamulusclient/getConnectionState. New notifications: jamulusclient/connecting, jamulusclient/connectingFailed and jamulusclient/connectionStateChanged. Together with the existing connected/disconnected notifications this gives JSON-RPC full parity with the UI for joining and leaving servers (jamulussoftware#3801) and makes a --nogui client fully scriptable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirror the new --connectdirectory option on the RPC side: connect now accepts an optional "directory" param. When given, CClient::Connect hole-punches through that directory (CLM_REQ_SERVER_LIST) before connecting, so an RPC-driven client can reach a server behind a cloud firewall/NAT the same way the GUI directory list does. A non-string directory is rejected with invalid params; the server address is connected to verbatim and need not be listed by the directory. docs/JSON-RPC.md regenerated via tools/generate_json_rpc_docs.py. Relates to jamulussoftware/jamuluswebsite#1122 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cecdea1 to
2fbbc35
Compare
Short description of changes
Stacked on #3805 — please review only the last commit here until that one merges.
Adds JSON-RPC control over the client's connection, as a symmetric consumer of the
CClientconnection state machine introduced in #3805. This closes the largest UI/RPC parity gap named in #3801 (join/leave) and makes a--noguiclient fully scriptable — e.g. a local web frontend where clicking a server joins it.New methods:
jamulusclient/connect{"address": "host:port", "serverName": "optional display name"}— terminates any current connection first, then connects (asynchronously; progress arrives via notifications).jamulusclient/disconnect— idempotent.jamulusclient/getConnectionState— returns{state: disconnected|connecting|connected, serverName}.New notifications:
jamulusclient/connecting,jamulusclient/connectingFailed,jamulusclient/connectionStateChanged. Together with the existingconnected/disconnectednotifications, an RPC consumer can follow the full lifecycle.Context: Fixes an issue?
Toward #3801 (full UI/RPC parity). Complementary to #3660 (directory getters).
Does this change need documentation? What needs to be documented and how?
docs/JSON-RPC.mdregenerated viatools/generate_json_rpc_docs.py(included).Status of this Pull Request
Draft until #3805 merges; the RPC commit itself is ready for review.
What is missing until this pull request can be merged?
#3805, then review.
Tested end-to-end:
--noguiclient + local server on Linux/Qt 5.15, driven entirely over JSON-RPC. Scripted checks (16/16 pass): initial statedisconnected;connect→connectingnotification →connectionStateChanged: connecting→connected(channel ID) →connectionStateChanged: connected→getConnectionStatereturns server name; connect-while-connected performs a clean reconnect (disconnected→connecting→connected);disconnect→disconnected+connectionStateChanged: disconnected,serverNamecleared; double disconnect is a no-op.Checklist
AUTOBUILD: Please build all targets
🤖 Generated with Claude Code