mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-12 16:46:42 +02:00
json rpc basics
This commit is contained in:
parent
1b579ed2a6
commit
6121fdceae
6 changed files with 120 additions and 73 deletions
|
@ -1,4 +1,4 @@
|
||||||
VERSION = 0.3.2
|
VERSION = 0.3.90
|
||||||
TARGET = snapclient
|
TARGET = snapclient
|
||||||
SHELL = /bin/bash
|
SHELL = /bin/bash
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ CXX = /usr/bin/g++
|
||||||
CFLAGS = -std=c++0x -Wall -Wno-unused-function -O3 -pthread -DVERSION=\"$(VERSION)\" -I..
|
CFLAGS = -std=c++0x -Wall -Wno-unused-function -O3 -pthread -DVERSION=\"$(VERSION)\" -I..
|
||||||
LDFLAGS = -lrt -lboost_system -lboost_program_options -lvorbis -lvorbisenc -logg -lFLAC -lavahi-client -lavahi-common
|
LDFLAGS = -lrt -lboost_system -lboost_program_options -lvorbis -lvorbisenc -logg -lFLAC -lavahi-client -lavahi-common
|
||||||
|
|
||||||
OBJ = snapServer.o controlServer.o controlSession.o streamServer.o encoder/encoderFactory.o encoder/flacEncoder.o encoder/pcmEncoder.o encoder/oggEncoder.o serverSession.o publishAvahi.o pipeReader.o ../common/log.o ../message/pcmChunk.o ../message/sampleFormat.o
|
OBJ = snapServer.o config.o controlServer.o controlSession.o streamServer.o jsonrpc.o encoder/encoderFactory.o encoder/flacEncoder.o encoder/pcmEncoder.o encoder/oggEncoder.o serverSession.o publishAvahi.o pipeReader.o ../common/log.o ../message/pcmChunk.o ../message/sampleFormat.o
|
||||||
BIN = snapserver
|
BIN = snapserver
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
|
#include "boost/lexical_cast.hpp"
|
||||||
#include "controlServer.h"
|
#include "controlServer.h"
|
||||||
#include "message/time.h"
|
#include "message/time.h"
|
||||||
#include "message/ack.h"
|
#include "message/ack.h"
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
#include "message/command.h"
|
#include "message/command.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/snapException.h"
|
#include "common/snapException.h"
|
||||||
#include "json.hpp"
|
#include "jsonrpc.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -81,91 +82,81 @@ void ControlServer::onMessageReceived(ControlSession* connection, const std::str
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int id = -1;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// http://www.jsonrpc.org/specification
|
JsonRequest jsonRequest;
|
||||||
// code message meaning
|
jsonRequest.parse(message);
|
||||||
// -32700 Parse error Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.
|
|
||||||
// -32600 Invalid Request The JSON sent is not a valid Request object.
|
|
||||||
|
//{"jsonrpc": "2.0", "method": "get", "id": 2}
|
||||||
|
//{"jsonrpc": "2.0", "method": "get", "params": ["status"], "id": 2}
|
||||||
|
//{"jsonrpc": "2.0", "method": "get", "params": ["status", "server"], "id": 2}
|
||||||
|
//{"jsonrpc": "2.0", "method": "get", "params": ["status", "client"], "id": 2}
|
||||||
|
//{"jsonrpc": "2.0", "method": "get", "params": ["status", "client", "MAC"], "id": 2}
|
||||||
|
//{"jsonrpc": "2.0", "method": "test", "params": ["status", "client", "MAC"], "id": 2}
|
||||||
|
//{"jsonrpc": "2.0", "method": "set", "params": ["voume", "client", "MAC", "1.0"], "id": 2}
|
||||||
|
|
||||||
// -32601 Method not found The method does not exist / is not available.
|
// -32601 Method not found The method does not exist / is not available.
|
||||||
// -32602 Invalid params Invalid method parameter(s).
|
// -32602 Invalid params Invalid method parameter(s).
|
||||||
// -32603 Internal error Internal JSON-RPC error.
|
// -32603 Internal error Internal JSON-RPC error.
|
||||||
// -32000 to -32099 Server error Reserved for implementation-defined server-errors.
|
|
||||||
json request;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
request = json::parse(message);
|
|
||||||
}
|
|
||||||
catch (const exception& e)
|
|
||||||
{
|
|
||||||
throw SnapException(e.what(), -32700);
|
|
||||||
}
|
|
||||||
|
|
||||||
id = request["id"].get<int>();
|
logO << "method: " << jsonRequest.method << ", " << "id: " << jsonRequest.id << "\n";
|
||||||
string jsonrpc = request["jsonrpc"].get<string>();
|
for (string s: jsonRequest.params)
|
||||||
if (jsonrpc != "2.0")
|
logO << "param: " << s << "\n";
|
||||||
throw SnapException("invalid jsonrpc value: " + jsonrpc, -32600);
|
|
||||||
string method = request["method"].get<string>();
|
|
||||||
if (method.empty())
|
|
||||||
throw SnapException("method must not be empty", -32600);
|
|
||||||
if (id < 0)
|
|
||||||
throw SnapException("id must be a positive integer", -32600);
|
|
||||||
|
|
||||||
json response = {
|
if (jsonRequest.params.empty())
|
||||||
{"jsonrpc", "2.0"},
|
throw JsonInvalidParamsException(jsonRequest);
|
||||||
{"id", id}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (method == "get")
|
vector<string>& params = jsonRequest.params;
|
||||||
|
if (jsonRequest.method == "get")
|
||||||
{
|
{
|
||||||
response["result"] = "???";//nullptr;
|
if (params[0] == "status")
|
||||||
}
|
|
||||||
else if (method == "set")
|
|
||||||
{
|
{
|
||||||
response["result"] = "234";//nullptr;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw SnapException("method not found: \"" + method + "\"", -32601);
|
throw JsonInvalidParamsException(jsonRequest);
|
||||||
|
|
||||||
connection->send(response.dump());
|
|
||||||
}
|
}
|
||||||
catch (const SnapException& e)
|
else if (jsonRequest.method == "set")
|
||||||
{
|
{
|
||||||
throw;
|
if (params[0] == "volume")
|
||||||
}
|
|
||||||
catch (const exception& e)
|
|
||||||
{
|
{
|
||||||
throw SnapException(e.what(), -32603);
|
if ((params.size() < 4) || (params[1] != "client"))
|
||||||
}
|
throw JsonInvalidParamsException(jsonRequest);
|
||||||
}
|
try
|
||||||
catch (const SnapException& e)
|
|
||||||
{
|
{
|
||||||
int errorCode = e.errorCode();
|
double volume = boost::lexical_cast<double>(params[3]);
|
||||||
if (errorCode == 0)
|
}
|
||||||
errorCode = -32603;
|
catch(...)
|
||||||
|
{
|
||||||
|
throw JsonInvalidParamsException(jsonRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (params[0] == "latency")
|
||||||
|
{
|
||||||
|
if ((params.size() < 3) || (params[1] != "client"))
|
||||||
|
throw JsonInvalidParamsException(jsonRequest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw JsonInvalidParamsException(jsonRequest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw JsonMethodNotFoundException(jsonRequest);
|
||||||
|
|
||||||
json response = {
|
json response = {
|
||||||
{"jsonrpc", "2.0"},
|
{"test", "123"},
|
||||||
{"error", {
|
{"error", {
|
||||||
{"code", errorCode},
|
{"code", 12},
|
||||||
{"message", e.what()}
|
{"message", true}
|
||||||
}},
|
}}};
|
||||||
};
|
|
||||||
if (id == -1)
|
|
||||||
response["id"] = nullptr;
|
|
||||||
else
|
|
||||||
response["id"] = id;
|
|
||||||
|
|
||||||
connection->send(response.dump());
|
connection->send(jsonRequest.getResponse(response).dump());
|
||||||
|
}
|
||||||
|
catch (const JsonRequestException& e)
|
||||||
|
{
|
||||||
|
connection->send(e.getResponse().dump());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//get status
|
|
||||||
//get status server
|
|
||||||
//get status client[:MAC]
|
|
||||||
//set volume client[:MAC] {VOLUME}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "encoder/encoderFactory.h"
|
#include "encoder/encoderFactory.h"
|
||||||
#include "streamServer.h"
|
#include "streamServer.h"
|
||||||
#include "publishAvahi.h"
|
#include "publishAvahi.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
bool g_terminated = false;
|
bool g_terminated = false;
|
||||||
|
@ -53,6 +54,7 @@ int main(int argc, char* argv[])
|
||||||
po::options_description desc("Allowed options");
|
po::options_description desc("Allowed options");
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce help message")
|
("help,h", "produce help message")
|
||||||
|
("test", "for testing")
|
||||||
("version,v", "show version number")
|
("version,v", "show version number")
|
||||||
("port,p", po::value<size_t>(&settings.port)->default_value(settings.port), "server port")
|
("port,p", po::value<size_t>(&settings.port)->default_value(settings.port), "server port")
|
||||||
("sampleformat,s", po::value<string>(&sampleFormat)->default_value(settings.sampleFormat.getFormat()), "sample format")
|
("sampleformat,s", po::value<string>(&sampleFormat)->default_value(settings.sampleFormat.getFormat()), "sample format")
|
||||||
|
@ -67,6 +69,12 @@ int main(int argc, char* argv[])
|
||||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
|
if (vm.count("test"))
|
||||||
|
{
|
||||||
|
Config::instance().test();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (vm.count("help"))
|
if (vm.count("help"))
|
||||||
{
|
{
|
||||||
cout << desc << "\n";
|
cout << desc << "\n";
|
||||||
|
|
49
server/snapserver.json
Normal file
49
server/snapserver.json
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{
|
||||||
|
"Zone":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"uri": "file:///tmp/SnapCast/snapfifo",
|
||||||
|
"name": "zone 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uri": "file:///tmp/SnapCast/snapfifo2",
|
||||||
|
"name": "zone 2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"Client":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"MAC": "00:21:6a:7d:74:fc",
|
||||||
|
"IP": "10.1.2.3",
|
||||||
|
"host": "T400",
|
||||||
|
"version": "1.2",
|
||||||
|
"name": "living room",
|
||||||
|
"volume": 0.9,
|
||||||
|
"lastSeen":
|
||||||
|
{
|
||||||
|
"sec": 99,
|
||||||
|
"usec": 1
|
||||||
|
},
|
||||||
|
"conntected": true,
|
||||||
|
"zone": "file:///tmp/SnapCast/snapfifo",
|
||||||
|
"latency": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"MAC": "11:21:6a:7d:74:fc",
|
||||||
|
"IP": "10.1.2.3",
|
||||||
|
"host": "T400",
|
||||||
|
"version": "1.2",
|
||||||
|
"name": "kitchen",
|
||||||
|
"volume": 0.9,
|
||||||
|
"lastSeen":
|
||||||
|
{
|
||||||
|
"sec": 99,
|
||||||
|
"usec": 1
|
||||||
|
},
|
||||||
|
"status": 0,
|
||||||
|
"zone": "file:///tmp/SnapCast/snapfifo",
|
||||||
|
"latency": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -120,7 +120,7 @@ void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseM
|
||||||
{
|
{
|
||||||
msg::Command commandMsg;
|
msg::Command commandMsg;
|
||||||
commandMsg.deserialize(baseMessage, buffer);
|
commandMsg.deserialize(baseMessage, buffer);
|
||||||
if (commandMsg.command == "startStream")
|
if (commandMsg.getCommand() == "startStream")
|
||||||
{
|
{
|
||||||
msg::Ack ackMsg;
|
msg::Ack ackMsg;
|
||||||
ackMsg.refersTo = commandMsg.id;
|
ackMsg.refersTo = commandMsg.id;
|
||||||
|
@ -132,8 +132,8 @@ void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseM
|
||||||
{
|
{
|
||||||
msg::Hello helloMsg;
|
msg::Hello helloMsg;
|
||||||
helloMsg.deserialize(baseMessage, buffer);
|
helloMsg.deserialize(baseMessage, buffer);
|
||||||
connection->macAddress = helloMsg.macAddress;
|
connection->macAddress = helloMsg.getMacAddress();
|
||||||
logO << "Hello from " << connection->macAddress << "\n";
|
logO << "Hello from " << connection->macAddress << ", host: " << helloMsg.getHostName() << ", v" << helloMsg.getVersion() << "\n";
|
||||||
json j = {
|
json j = {
|
||||||
{"event", "newConnection"},
|
{"event", "newConnection"},
|
||||||
{"client", {
|
{"client", {
|
||||||
|
@ -142,7 +142,6 @@ void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseM
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
controlServer->send(j.dump());
|
controlServer->send(j.dump());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue