Skip to content

Commit 9b05025

Browse files
authored
Merge pull request #3479 from ann0see/jsonrpc/addDirectoryMethods
Add JSON-RPC access to directories and server lists (without connect/disconnect methods)
2 parents 165efbc + 9c95bed commit 9b05025

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed

docs/JSON-RPC.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ Results:
147147
| result.name | string | The musician’s name. |
148148
| result.skillLevel | string | The musician’s skill level (beginner, intermediate, expert, or null). |
149149
| result.countryId | number | The musician’s country ID (see QLocale::Country). |
150+
| result.country | string | The musician’s country. |
150151
| result.city | string | The musician’s city. |
151152
| result.instrumentId | number | The musician’s instrument ID (see CInstPictures::GetTable). |
153+
| result.instrument | string | The musician’s instrument. |
152154
| result.skillLevel | string | Your skill level (beginner, intermediate, expert, or null). |
153155

154156

@@ -186,6 +188,23 @@ Results:
186188
| result.clients | array | The client list. See jamulusclient/clientListReceived for the format. |
187189

188190

191+
### jamulusclient/pollServerList
192+
193+
Request list of servers in a directory.
194+
195+
Parameters:
196+
197+
| Name | Type | Description |
198+
| --- | --- | --- |
199+
| params.directory | string | Socket address of directory to query. Example: anygenre1.jamulus.io:22124 |
200+
201+
Results:
202+
203+
| Name | Type | Description |
204+
| --- | --- | --- |
205+
| result | string | "ok" or "error" if bad arguments. |
206+
207+
189208
### jamulusclient/sendChatText
190209

191210
Sends a chat text message.
@@ -445,8 +464,10 @@ Parameters:
445464
| params.clients[*].name | string | The musician’s name. |
446465
| params.clients[*].skillLevel | string | The musician’s skill level (beginner, intermediate, expert, or null). |
447466
| params.clients[*].countryId | number | The musician’s country ID (see QLocale::Country). |
467+
| params.clients[*].country | string | The musician’s country. |
448468
| params.clients[*].city | string | The musician’s city. |
449469
| params.clients[*].instrumentId | number | The musician’s instrument ID (see CInstPictures::GetTable). |
470+
| params.clients[*].instrument | string | The musician’s instrument. |
450471

451472

452473
### jamulusclient/connected
@@ -471,3 +492,43 @@ Parameters:
471492
| params | object | No parameters (empty object). |
472493

473494

495+
### jamulusclient/recorderState
496+
497+
Emitted when the client is connected to a server whose recorder state changes.
498+
499+
Parameters:
500+
501+
| Name | Type | Description |
502+
| --- | --- | --- |
503+
| params.state | number | The recorder state. |
504+
505+
506+
### jamulusclient/serverInfoReceived
507+
508+
Emitted when a server info is received.
509+
510+
Parameters:
511+
512+
| Name | Type | Description |
513+
| --- | --- | --- |
514+
| params.address | string | The server socket address. |
515+
| params.pingtime | number | The round-trip ping time, in milliseconds. |
516+
| params.numClients | number | The number of clients connected to the server. |
517+
518+
519+
### jamulusclient/serverListReceived
520+
521+
Emitted when the server list is received.
522+
523+
Parameters:
524+
525+
| Name | Type | Description |
526+
| --- | --- | --- |
527+
| params.servers | array | The server list. |
528+
| params.servers[*].address | string | Socket address (ip_address:port). |
529+
| params.servers[*].name | string | Server name. |
530+
| params.servers[*].countryId | number | Server country ID (see QLocale::Country). |
531+
| params.servers[*].country | string | Server country. |
532+
| params.servers[*].city | string | Server city. |
533+
534+

src/client.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ class CClient : public QObject
286286
Channel.GetBufErrorRates ( vecErrRates, dLimit, dMaxUpLimit );
287287
}
288288

289+
//### TODO: BEGIN ###//
290+
// Refactor this to use signal/slot mechanism. https://github.com/jamulussoftware/jamulus/pull/3479/files#r1976382416
291+
CProtocol* getConnLessProtocol() { return &ConnLessProtocol; }
292+
//### TODO: END ###//
293+
289294
// settings
290295
CChannelCoreInfo ChannelInfo;
291296
QString strClientName;

src/clientrpc.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ CClientRpc::CClientRpc ( CClient* pClient, CRpcServer* pRpcServer, QObject* pare
5454
/// @param {string} params.clients[*].name - The musician’s name.
5555
/// @param {string} params.clients[*].skillLevel - The musician’s skill level (beginner, intermediate, expert, or null).
5656
/// @param {number} params.clients[*].countryId - The musician’s country ID (see QLocale::Country).
57+
/// @param {string} params.clients[*].country - The musician’s country.
5758
/// @param {string} params.clients[*].city - The musician’s city.
5859
/// @param {number} params.clients[*].instrumentId - The musician’s instrument ID (see CInstPictures::GetTable).
60+
/// @param {string} params.clients[*].instrument - The musician’s instrument.
5961
connect ( pClient, &CClient::ConClientListMesReceived, [=] ( CVector<CChannelInfo> vecChanInfo ) {
6062
QJsonArray arrChanInfo;
6163
for ( const auto& chanInfo : vecChanInfo )
@@ -65,8 +67,10 @@ CClientRpc::CClientRpc ( CClient* pClient, CRpcServer* pRpcServer, QObject* pare
6567
{ "name", chanInfo.strName },
6668
{ "skillLevel", SerializeSkillLevel ( chanInfo.eSkillLevel ) },
6769
{ "countryId", chanInfo.eCountry },
70+
{ "country", QLocale::countryToString ( chanInfo.eCountry ) },
6871
{ "city", chanInfo.strCity },
6972
{ "instrumentId", chanInfo.iInstrument },
73+
{ "instrument", CInstPictures::GetName ( chanInfo.iInstrument ) },
7074
};
7175
arrChanInfo.append ( objChanInfo );
7276
}
@@ -94,11 +98,87 @@ CClientRpc::CClientRpc ( CClient* pClient, CRpcServer* pRpcServer, QObject* pare
9498
} );
9599
} );
96100

101+
/// @rpc_notification jamulusclient/serverListReceived
102+
/// @brief Emitted when the server list is received.
103+
/// @param {array} params.servers - The server list.
104+
/// @param {string} params.servers[*].address - Socket address (ip_address:port).
105+
/// @param {string} params.servers[*].name - Server name.
106+
/// @param {number} params.servers[*].countryId - Server country ID (see QLocale::Country).
107+
/// @param {string} params.servers[*].country - Server country.
108+
/// @param {string} params.servers[*].city - Server city.
109+
connect ( pClient->getConnLessProtocol(),
110+
&CProtocol::CLServerListReceived,
111+
[=] ( CHostAddress /* unused */, CVector<CServerInfo> vecServerInfo ) {
112+
QJsonArray arrServerInfo;
113+
for ( const auto& serverInfo : vecServerInfo )
114+
{
115+
QJsonObject objServerInfo{
116+
{ "address", serverInfo.HostAddr.toString() },
117+
{ "name", serverInfo.strName },
118+
{ "countryId", serverInfo.eCountry },
119+
{ "country", QLocale::countryToString ( serverInfo.eCountry ) },
120+
{ "city", serverInfo.strCity },
121+
};
122+
arrServerInfo.append ( objServerInfo );
123+
pClient->CreateCLServerListPingMes ( serverInfo.HostAddr );
124+
}
125+
pRpcServer->BroadcastNotification ( "jamulusclient/serverListReceived",
126+
QJsonObject{
127+
{ "servers", arrServerInfo },
128+
} );
129+
} );
130+
131+
/// @rpc_notification jamulusclient/serverInfoReceived
132+
/// @brief Emitted when a server info is received.
133+
/// @param {string} params.address - The server socket address.
134+
/// @param {number} params.pingtime - The round-trip ping time, in milliseconds.
135+
/// @param {number} params.numClients - The number of clients connected to the server.
136+
connect ( pClient, &CClient::CLPingTimeWithNumClientsReceived, [=] ( CHostAddress InetAddr, int iPingTime, int iNumClients ) {
137+
pRpcServer->BroadcastNotification (
138+
"jamulusclient/serverInfoReceived",
139+
QJsonObject{ { "address", InetAddr.toString() }, { "pingTime", iPingTime }, { "numClients", iNumClients } } );
140+
} );
141+
97142
/// @rpc_notification jamulusclient/disconnected
98143
/// @brief Emitted when the client is disconnected from the server.
99144
/// @param {object} params - No parameters (empty object).
100145
connect ( pClient, &CClient::Disconnected, [=]() { pRpcServer->BroadcastNotification ( "jamulusclient/disconnected", QJsonObject{} ); } );
101146

147+
/// @rpc_notification jamulusclient/recorderState
148+
/// @brief Emitted when the client is connected to a server whose recorder state changes.
149+
/// @param {number} params.state - The recorder state.
150+
connect ( pClient, &CClient::RecorderStateReceived, [=] ( const ERecorderState newRecorderState ) {
151+
pRpcServer->BroadcastNotification ( "jamulusclient/recorderState", QJsonObject{ { "state", newRecorderState } } );
152+
} );
153+
154+
/// @rpc_method jamulusclient/pollServerList
155+
/// @brief Request list of servers in a directory.
156+
/// @param {string} params.directory - Socket address of directory to query. Example: anygenre1.jamulus.io:22124
157+
/// @result {string} result - "ok" or "error" if bad arguments.
158+
pRpcServer->HandleMethod ( "jamulusclient/pollServerList", [=] ( const QJsonObject& params, QJsonObject& response ) {
159+
auto jsonDirectoryIp = params["directory"];
160+
if ( !jsonDirectoryIp.isString() )
161+
{
162+
response["error"] = CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: directory is not a string" );
163+
return;
164+
}
165+
166+
CHostAddress haDirectoryAddress;
167+
if ( NetworkUtil().ParseNetworkAddress ( jsonDirectoryIp.toString(), haDirectoryAddress, false ) )
168+
{
169+
// send the request for the server list
170+
pClient->CreateCLReqServerListMes ( haDirectoryAddress );
171+
response["result"] = "ok";
172+
}
173+
else
174+
{
175+
response["error"] =
176+
CRpcServer::CreateJsonRpcError ( CRpcServer::iErrInvalidParams, "Invalid params: directory is not a valid socket address" );
177+
}
178+
179+
response["result"] = "ok";
180+
} );
181+
102182
/// @rpc_method jamulus/getMode
103183
/// @brief Returns the current mode, i.e. whether Jamulus is running as a server or client.
104184
/// @param {object} params - No parameters (empty object).
@@ -126,16 +206,20 @@ CClientRpc::CClientRpc ( CClient* pClient, CRpcServer* pRpcServer, QObject* pare
126206
/// @result {string} result.name - The musician’s name.
127207
/// @result {string} result.skillLevel - The musician’s skill level (beginner, intermediate, expert, or null).
128208
/// @result {number} result.countryId - The musician’s country ID (see QLocale::Country).
209+
/// @result {string} result.country - The musician’s country.
129210
/// @result {string} result.city - The musician’s city.
130211
/// @result {number} result.instrumentId - The musician’s instrument ID (see CInstPictures::GetTable).
212+
/// @result {string} result.instrument - The musician’s instrument.
131213
/// @result {string} result.skillLevel - Your skill level (beginner, intermediate, expert, or null).
132214
pRpcServer->HandleMethod ( "jamulusclient/getChannelInfo", [=] ( const QJsonObject& params, QJsonObject& response ) {
133215
QJsonObject result{
134216
// TODO: We cannot include "id" here is pClient->ChannelInfo is a CChannelCoreInfo which lacks that field.
135217
{ "name", pClient->ChannelInfo.strName },
136218
{ "countryId", pClient->ChannelInfo.eCountry },
219+
{ "country", QLocale::countryToString ( pClient->ChannelInfo.eCountry ) },
137220
{ "city", pClient->ChannelInfo.strCity },
138221
{ "instrumentId", pClient->ChannelInfo.iInstrument },
222+
{ "instrument", CInstPictures::GetName ( pClient->ChannelInfo.iInstrument ) },
139223
{ "skillLevel", SerializeSkillLevel ( pClient->ChannelInfo.eSkillLevel ) },
140224
};
141225
response["result"] = result;

0 commit comments

Comments
 (0)