mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-17 11:06:16 +02:00
Json RPC: Object.Set methods have the updated object in the response
This commit is contained in:
parent
c1eca56e38
commit
9e96b3e13b
5 changed files with 248 additions and 167 deletions
|
@ -20,7 +20,6 @@ package de.badaix.snapcast;
|
|||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
@ -64,7 +63,7 @@ public class ClientItem extends LinearLayout implements SeekBar.OnSeekBarChangeL
|
|||
}
|
||||
|
||||
private void update() {
|
||||
Log.d(TAG, "update: " + client.getVisibleName() + ", connected: " + client.isConnected());
|
||||
//Log.d(TAG, "update: " + client.getVisibleName() + ", connected: " + client.isConnected());
|
||||
title.setText(client.getVisibleName());
|
||||
title.setEnabled(client.isConnected());
|
||||
volumeSeekBar.setProgress(client.getConfig().getVolume().getPercent());
|
||||
|
|
|
@ -55,6 +55,7 @@ import java.util.ArrayList;
|
|||
|
||||
import de.badaix.snapcast.control.RemoteControl;
|
||||
import de.badaix.snapcast.control.json.Client;
|
||||
import de.badaix.snapcast.control.json.Group;
|
||||
import de.badaix.snapcast.control.json.ServerStatus;
|
||||
import de.badaix.snapcast.control.json.Stream;
|
||||
import de.badaix.snapcast.utils.NsdHelper;
|
||||
|
@ -431,8 +432,9 @@ public class MainActivity extends AppCompatActivity implements GroupItem.GroupIt
|
|||
remoteControl.setStream(groupId, streamId);
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
remoteControl.getServerStatus();
|
||||
//TODO
|
||||
// if (changed)
|
||||
// remoteControl.getServerStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,7 +469,7 @@ public class MainActivity extends AppCompatActivity implements GroupItem.GroupIt
|
|||
@Override
|
||||
public void onClientEvent(RemoteControl remoteControl, Client client, RemoteControl.ClientEvent event) {
|
||||
Log.d(TAG, "onClientEvent: " + event.toString());
|
||||
remoteControl.getServerStatus();
|
||||
// remoteControl.getServerStatus();
|
||||
/* TODO: group
|
||||
if (event == RemoteControl.ClientEvent.deleted)
|
||||
serverStatus.removeClient(client);
|
||||
|
@ -475,6 +477,9 @@ public class MainActivity extends AppCompatActivity implements GroupItem.GroupIt
|
|||
serverStatus.updateClient(client);
|
||||
sectionsPagerAdapter.updateServer(serverStatus);
|
||||
*/
|
||||
if (event != RemoteControl.ClientEvent.deleted)
|
||||
serverStatus.updateClient(client);
|
||||
groupListFragment.updateServer(serverStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -489,6 +494,12 @@ public class MainActivity extends AppCompatActivity implements GroupItem.GroupIt
|
|||
// TODO: group sectionsPagerAdapter.updateServer(serverStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGroupUpdate(RemoteControl remoteControl, Group group) {
|
||||
// TODO
|
||||
Log.d(TAG, "onGroupUpdate: " + group.toString());
|
||||
}
|
||||
|
||||
|
||||
private void setActionbarSubtitle(final String subtitle) {
|
||||
MainActivity.this.runOnUiThread(new Runnable() {
|
||||
|
|
|
@ -44,14 +44,12 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
|||
private TcpClient tcpClient;
|
||||
private long msgId;
|
||||
private RemoteControlListener listener;
|
||||
private ServerStatus serverStatus;
|
||||
private String host;
|
||||
private int port;
|
||||
private HashMap<Long, String> pendingRequests;
|
||||
|
||||
public RemoteControl(RemoteControlListener listener) {
|
||||
this.listener = listener;
|
||||
serverStatus = new ServerStatus();
|
||||
msgId = 0;
|
||||
pendingRequests = new HashMap<>();
|
||||
}
|
||||
|
@ -96,7 +94,9 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
|||
// Log.d(TAG, "Msg received: " + message);
|
||||
try {
|
||||
JSONObject json = new JSONObject(message);
|
||||
|
||||
if (json.has("id")) {
|
||||
/// Response
|
||||
// Log.d(TAG, "ID: " + json.getString("id"));
|
||||
long id = json.getLong("id");
|
||||
String request = "";
|
||||
|
@ -107,38 +107,53 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
|||
pendingRequests.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (listener == null)
|
||||
return;
|
||||
|
||||
if (json.has("error")) {
|
||||
JSONObject error = json.getJSONObject("error");
|
||||
Log.e(TAG, "error " + error.getInt("code") + ": " + error.getString("message"));
|
||||
} else if (!TextUtils.isEmpty(request)) {
|
||||
if (request.equals("Server.GetStatus")) {
|
||||
serverStatus.fromJson(json.getJSONObject("result"));
|
||||
if (listener != null)
|
||||
listener.onServerStatus(this, serverStatus);
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(request)) {
|
||||
Log.e(TAG, "request for id " + id + " not found");
|
||||
return;
|
||||
}
|
||||
|
||||
/// Response to a "Object.GetStatus" message
|
||||
if (request.equals("Client.GetStatus")) {
|
||||
listener.onClientEvent(this, new Client(json.getJSONObject("result")), ClientEvent.updated);
|
||||
} else if (request.equals("Group.GetStatus")) {
|
||||
listener.onGroupUpdate(this, new Group(json.getJSONObject("result")));
|
||||
} else if (request.equals("Server.GetStatus")) {
|
||||
listener.onServerStatus(this, new ServerStatus(json.getJSONObject("result")));
|
||||
} else if (json.getJSONObject("result").has("method") && json.getJSONObject("result").has("params")) {
|
||||
/// Response to a "Object.Set" message
|
||||
JSONObject result = json.getJSONObject("result");
|
||||
String method = result.getString("method");
|
||||
if ("Client.OnUpdate".equals(method)) {
|
||||
// listener.onClientEvent(this, new Client(result.getJSONObject("params")), ClientEvent.updated);
|
||||
} else if ("Group.OnUpdate".equals(method)) {
|
||||
listener.onGroupUpdate(this, new Group(result.getJSONObject("params")));
|
||||
} else if ("Server.OnUpdate".equals(method)) {
|
||||
listener.onServerStatus(this, new ServerStatus(result.getJSONObject("params")));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/// Notification
|
||||
if (listener == null)
|
||||
return;
|
||||
String method = json.getString("method");
|
||||
// Log.d(TAG, "Notification: " + method);
|
||||
if (method.contains("Client.On")) {
|
||||
final Client client = new Client(json.getJSONObject("params").getJSONObject("data"));
|
||||
// serverStatus.addClient(client);
|
||||
if (listener != null) {
|
||||
ClientEvent event;
|
||||
if (method.equals("Client.OnUpdate"))
|
||||
listener.onClientEvent(this, client, ClientEvent.updated);
|
||||
else if (method.equals("Client.OnConnect"))
|
||||
listener.onClientEvent(this, client, ClientEvent.connected);
|
||||
else if (method.equals("Client.OnDisconnect"))
|
||||
listener.onClientEvent(this, client, ClientEvent.disconnected);
|
||||
else if (method.equals("Client.OnDelete")) {
|
||||
listener.onClientEvent(this, client, ClientEvent.deleted);
|
||||
}
|
||||
}
|
||||
final Client client = new Client(json.getJSONObject("params"));
|
||||
listener.onClientEvent(this, client, ClientEvent.fromString(method));
|
||||
} else if (method.equals("Stream.OnUpdate")) {
|
||||
Stream stream = new Stream(json.getJSONObject("params").getJSONObject("data"));
|
||||
listener.onStreamUpdate(this, stream);
|
||||
Log.d(TAG, stream.toString());
|
||||
listener.onStreamUpdate(this, new Stream(json.getJSONObject("params")));
|
||||
} else if (method.equals("Group.OnUpdate")) {
|
||||
listener.onGroupUpdate(this, new Group(json.getJSONObject("params")));
|
||||
} else if (method.equals("Server.OnUpdate")) {
|
||||
listener.onServerStatus(this, new ServerStatus(json.getJSONObject("params")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +172,6 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
|||
@Override
|
||||
public void onConnected(TcpClient tcpClient) {
|
||||
Log.d(TAG, "onConnected");
|
||||
serverStatus = new ServerStatus();
|
||||
if (listener != null)
|
||||
listener.onConnected(this);
|
||||
}
|
||||
|
@ -165,7 +179,6 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
|||
@Override
|
||||
public void onDisconnected(TcpClient tcpClient, Exception e) {
|
||||
Log.d(TAG, "onDisconnected");
|
||||
serverStatus = null;
|
||||
if (listener != null)
|
||||
listener.onDisconnected(this, e);
|
||||
}
|
||||
|
@ -262,10 +275,30 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
|||
}
|
||||
|
||||
public enum ClientEvent {
|
||||
connected,
|
||||
disconnected,
|
||||
updated,
|
||||
deleted
|
||||
connected("Client.OnConnect"),
|
||||
disconnected("Client.OnDisconnect"),
|
||||
updated("Client.OnUpdate"),
|
||||
deleted("Client.OnDelete");
|
||||
private String text;
|
||||
|
||||
ClientEvent(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public static ClientEvent fromString(String text) {
|
||||
if (text != null) {
|
||||
for (ClientEvent b : ClientEvent.values()) {
|
||||
if (text.equalsIgnoreCase(b.text)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("No ClientEvent with text " + text + " found");
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return this.text;
|
||||
}
|
||||
}
|
||||
|
||||
public interface RemoteControlListener {
|
||||
|
@ -280,5 +313,7 @@ public class RemoteControl implements TcpClient.TcpClientListener {
|
|||
void onServerStatus(RemoteControl remoteControl, ServerStatus serverStatus);
|
||||
|
||||
void onStreamUpdate(RemoteControl remoteControl, Stream stream);
|
||||
|
||||
void onGroupUpdate(RemoteControl remoteControl, Group group);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,9 +150,7 @@ Json JsonNotification::getJson(const std::string& method, Json data)
|
|||
Json notification = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"method", method},
|
||||
{"params", {
|
||||
{"data", data}
|
||||
}}
|
||||
{"params", data}
|
||||
};
|
||||
|
||||
return notification;
|
||||
|
|
|
@ -112,51 +112,68 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
|
|||
try
|
||||
{
|
||||
request.parse(message);
|
||||
logD << "method: " << request.method << ", " << "id: " << request.id << "\n";
|
||||
logO << "method: " << request.method << ", " << "id: " << request.id << "\n";
|
||||
|
||||
json response;
|
||||
ClientInfoPtr clientInfo = nullptr;
|
||||
GroupPtr group = nullptr;
|
||||
msg::ServerSettings serverSettings;
|
||||
serverSettings.setBufferMs(settings_.bufferMs);
|
||||
json result;
|
||||
|
||||
if (request.method.find("Group.Set") == 0)
|
||||
if (request.method.find("Client.") == 0)
|
||||
{
|
||||
group = Config::instance().getGroup(request.getParam("group").get<string>());
|
||||
if (group == nullptr)
|
||||
throw JsonInternalErrorException("Group not found", request.id);
|
||||
}
|
||||
|
||||
if (request.method.find("Client.Set") == 0)
|
||||
{
|
||||
clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>());
|
||||
ClientInfoPtr clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>());
|
||||
if (clientInfo == nullptr)
|
||||
throw JsonInternalErrorException("Client not found", request.id);
|
||||
}
|
||||
|
||||
if (request.method == "Server.GetStatus")
|
||||
if (request.method == "Client.GetStatus")
|
||||
{
|
||||
/// TODO: rpc
|
||||
string clientId = request.hasParam("client") ? request.getParam("client").get<string>() : "";
|
||||
response = Config::instance().getServerStatus(/*clientId,*/ streamManager_->toJson());
|
||||
// logO << response.dump(4);
|
||||
}
|
||||
else if (request.method == "Server.DeleteClient")
|
||||
{
|
||||
clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>());
|
||||
if (clientInfo == nullptr)
|
||||
throw JsonInternalErrorException("Client not found", request.id);
|
||||
response = clientInfo->host.mac;
|
||||
Config::instance().remove(clientInfo);
|
||||
Config::instance().save();
|
||||
json notification = JsonNotification::getJson("Client.OnDelete", clientInfo->toJson());
|
||||
controlServer_->send(notification.dump(), controlSession);
|
||||
clientInfo = nullptr;
|
||||
result = clientInfo->toJson();
|
||||
}
|
||||
else if (request.method == "Client.SetVolume")
|
||||
{
|
||||
clientInfo->config.volume.fromJson(request.getParam("volume"));
|
||||
response = clientInfo->config.volume.toJson();
|
||||
}
|
||||
else if (request.method == "Client.SetLatency")
|
||||
{
|
||||
clientInfo->config.latency = request.getParam<int>("latency", -10000, settings_.bufferMs);
|
||||
}
|
||||
else if (request.method == "Client.SetName")
|
||||
{
|
||||
clientInfo->config.name = request.getParam("name").get<string>();
|
||||
}
|
||||
else
|
||||
throw JsonMethodNotFoundException(request.id);
|
||||
|
||||
|
||||
if (request.method.find("Client.Set") == 0)
|
||||
{
|
||||
/// Response: updated client
|
||||
result = {{"method", "Client.OnUpdate"}, {"params", clientInfo->toJson()}};
|
||||
|
||||
/// Update client
|
||||
session_ptr session = getStreamSession(request.getParam("client").get<string>());
|
||||
if (session != nullptr)
|
||||
{
|
||||
msg::ServerSettings serverSettings;
|
||||
serverSettings.setBufferMs(settings_.bufferMs);
|
||||
serverSettings.setVolume(clientInfo->config.volume.percent);
|
||||
serverSettings.setMuted(clientInfo->config.volume.muted);
|
||||
serverSettings.setLatency(clientInfo->config.latency);
|
||||
session->send(&serverSettings);
|
||||
}
|
||||
|
||||
/// Notify others
|
||||
json notification = JsonNotification::getJson("Client.OnUpdate", clientInfo->toJson());
|
||||
logO << "Notification: " << notification.dump() << "\n";
|
||||
controlServer_->send(notification.dump(), controlSession);
|
||||
}
|
||||
}
|
||||
else if (request.method.find("Group.") == 0)
|
||||
{
|
||||
GroupPtr group = Config::instance().getGroup(request.getParam("group").get<string>());
|
||||
if (group == nullptr)
|
||||
throw JsonInternalErrorException("Group not found", request.id);
|
||||
|
||||
if (request.method == "Group.GetStatus")
|
||||
{
|
||||
result = group->toJson();
|
||||
}
|
||||
else if (request.method == "Group.SetStream")
|
||||
{
|
||||
|
@ -166,8 +183,11 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
|
|||
throw JsonInternalErrorException("Stream not found", request.id);
|
||||
|
||||
group->streamId = streamId;
|
||||
response = group->streamId;
|
||||
|
||||
/// Response: updated group
|
||||
result = {{"method", "Group.OnUpdate"}, {"params", group->toJson()}};
|
||||
|
||||
/// Update clients
|
||||
for (auto client: group->clients)
|
||||
{
|
||||
session_ptr session = getStreamSession(client->id);
|
||||
|
@ -177,6 +197,11 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
|
|||
session->setPcmStream(stream);
|
||||
}
|
||||
}
|
||||
|
||||
/// Notify others
|
||||
json notification = JsonNotification::getJson("Group.OnUpdate", group->toJson());
|
||||
logO << "Notification: " << notification.dump() << "\n";
|
||||
controlServer_->send(notification.dump(), controlSession);
|
||||
}
|
||||
else if (request.method == "Group.SetClients")
|
||||
{
|
||||
|
@ -228,37 +253,50 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
|
|||
|
||||
if (group->empty())
|
||||
Config::instance().remove(group);
|
||||
// response = Config::instance().getServerStatus(/*clientId,*/ streamManager_->toJson());
|
||||
|
||||
json serverJson = Config::instance().getServerStatus(streamManager_->toJson());
|
||||
result = {{"method", "Server.OnUpdate"}, {"params", serverJson}};
|
||||
|
||||
/// Notify others: since at least two groups are affected, send a complete server update
|
||||
json notification = JsonNotification::getJson("Server.OnUpdate", serverJson);
|
||||
logO << "Notification: " << notification.dump() << "\n";
|
||||
controlServer_->send(notification.dump(), controlSession);
|
||||
}
|
||||
else if (request.method == "Client.SetLatency")
|
||||
{
|
||||
clientInfo->config.latency = request.getParam<int>("latency", -10000, settings_.bufferMs);
|
||||
response = clientInfo->config.latency;
|
||||
else
|
||||
throw JsonMethodNotFoundException(request.id);
|
||||
}
|
||||
else if (request.method == "Client.SetName")
|
||||
else if (request.method.find("Server.") == 0)
|
||||
{
|
||||
clientInfo->config.name = request.getParam("name").get<string>();
|
||||
response = clientInfo->config.name;
|
||||
if (request.method == "Server.GetStatus")
|
||||
{
|
||||
result = Config::instance().getServerStatus(streamManager_->toJson());
|
||||
}
|
||||
else if (request.method == "Server.DeleteClient")
|
||||
{
|
||||
ClientInfoPtr clientInfo = Config::instance().getClientInfo(request.getParam("client").get<string>());
|
||||
if (clientInfo == nullptr)
|
||||
throw JsonInternalErrorException("Client not found", request.id);
|
||||
|
||||
Config::instance().remove(clientInfo);
|
||||
|
||||
json serverJson = Config::instance().getServerStatus(streamManager_->toJson());
|
||||
result = {{"method", "Server.OnUpdate"}, {"params", serverJson}};
|
||||
|
||||
/// Notify others
|
||||
json notification = JsonNotification::getJson("Server.OnUpdate", serverJson);
|
||||
logO << "Notification: " << notification.dump() << "\n";
|
||||
controlServer_->send(notification.dump(), controlSession);
|
||||
}
|
||||
else
|
||||
throw JsonMethodNotFoundException(request.id);
|
||||
}
|
||||
else
|
||||
throw JsonMethodNotFoundException(request.id);
|
||||
|
||||
if (clientInfo != nullptr)
|
||||
{
|
||||
serverSettings.setVolume(clientInfo->config.volume.percent);
|
||||
serverSettings.setMuted(clientInfo->config.volume.muted);
|
||||
serverSettings.setLatency(clientInfo->config.latency);
|
||||
|
||||
session_ptr session = getStreamSession(request.getParam("client").get<string>());
|
||||
if (session != nullptr)
|
||||
session->send(&serverSettings);
|
||||
|
||||
Config::instance().save();
|
||||
json notification = JsonNotification::getJson("Client.OnUpdate", clientInfo->toJson());
|
||||
controlServer_->send(notification.dump(), controlSession);
|
||||
}
|
||||
|
||||
controlSession->send(request.getResponse(response).dump());
|
||||
string responseJson = request.getResponse(result).dump();
|
||||
logO << "Response: " << responseJson << "\n";
|
||||
controlSession->send(responseJson);
|
||||
}
|
||||
catch (const JsonRequestException& e)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue