From 6121fdceae2924e44eb5487ac7e07eda9c94c2be Mon Sep 17 00:00:00 2001 From: badaix Date: Mon, 31 Aug 2015 23:40:41 +0200 Subject: [PATCH] json rpc basics --- client/Makefile | 2 +- server/Makefile | 2 +- server/controlServer.cpp | 125 ++++++++++++++++++--------------------- server/snapServer.cpp | 8 +++ server/snapserver.json | 49 +++++++++++++++ server/streamServer.cpp | 7 +-- 6 files changed, 120 insertions(+), 73 deletions(-) create mode 100644 server/snapserver.json diff --git a/client/Makefile b/client/Makefile index 3a8fa4a3..03be1dc3 100644 --- a/client/Makefile +++ b/client/Makefile @@ -1,4 +1,4 @@ -VERSION = 0.3.2 +VERSION = 0.3.90 TARGET = snapclient SHELL = /bin/bash diff --git a/server/Makefile b/server/Makefile index 8a643cb9..3667c309 100644 --- a/server/Makefile +++ b/server/Makefile @@ -6,7 +6,7 @@ CXX = /usr/bin/g++ 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 -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 all: $(TARGET) diff --git a/server/controlServer.cpp b/server/controlServer.cpp index e8e8392e..d5e8fa7c 100644 --- a/server/controlServer.cpp +++ b/server/controlServer.cpp @@ -16,6 +16,7 @@ along with this program. If not, see . ***/ +#include "boost/lexical_cast.hpp" #include "controlServer.h" #include "message/time.h" #include "message/ack.h" @@ -23,7 +24,7 @@ #include "message/command.h" #include "common/log.h" #include "common/snapException.h" -#include "json.hpp" +#include "jsonrpc.h" #include using namespace std; @@ -81,91 +82,81 @@ void ControlServer::onMessageReceived(ControlSession* connection, const std::str } else { - int id = -1; try { - // http://www.jsonrpc.org/specification - // code message meaning - // -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. + JsonRequest jsonRequest; + jsonRequest.parse(message); + + + //{"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. // -32602 Invalid params Invalid method parameter(s). // -32603 Internal error Internal JSON-RPC error. - // -32000 to -32099 Server error Reserved for implementation-defined server-errors. - json request; - try + + logO << "method: " << jsonRequest.method << ", " << "id: " << jsonRequest.id << "\n"; + for (string s: jsonRequest.params) + logO << "param: " << s << "\n"; + + if (jsonRequest.params.empty()) + throw JsonInvalidParamsException(jsonRequest); + + vector& params = jsonRequest.params; + if (jsonRequest.method == "get") { - try + if (params[0] == "status") { - request = json::parse(message); - } - catch (const exception& e) - { - throw SnapException(e.what(), -32700); - } - id = request["id"].get(); - string jsonrpc = request["jsonrpc"].get(); - if (jsonrpc != "2.0") - throw SnapException("invalid jsonrpc value: " + jsonrpc, -32600); - string method = request["method"].get(); - 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 = { - {"jsonrpc", "2.0"}, - {"id", id} - }; - - if (method == "get") - { - response["result"] = "???";//nullptr; - } - else if (method == "set") - { - response["result"] = "234";//nullptr; } else - throw SnapException("method not found: \"" + method + "\"", -32601); - - connection->send(response.dump()); + throw JsonInvalidParamsException(jsonRequest); } - catch (const SnapException& e) + else if (jsonRequest.method == "set") { - throw; + if (params[0] == "volume") + { + if ((params.size() < 4) || (params[1] != "client")) + throw JsonInvalidParamsException(jsonRequest); + try + { + double volume = boost::lexical_cast(params[3]); + } + catch(...) + { + throw JsonInvalidParamsException(jsonRequest); + } + } + else if (params[0] == "latency") + { + if ((params.size() < 3) || (params[1] != "client")) + throw JsonInvalidParamsException(jsonRequest); + } + else + throw JsonInvalidParamsException(jsonRequest); } - catch (const exception& e) - { - throw SnapException(e.what(), -32603); - } - } - catch (const SnapException& e) - { - int errorCode = e.errorCode(); - if (errorCode == 0) - errorCode = -32603; + else + throw JsonMethodNotFoundException(jsonRequest); json response = { - {"jsonrpc", "2.0"}, + {"test", "123"}, {"error", { - {"code", errorCode}, - {"message", e.what()} - }}, - }; - if (id == -1) - response["id"] = nullptr; - else - response["id"] = id; + {"code", 12}, + {"message", true} + }}}; - 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} } diff --git a/server/snapServer.cpp b/server/snapServer.cpp index c1103538..43ea4302 100644 --- a/server/snapServer.cpp +++ b/server/snapServer.cpp @@ -31,6 +31,7 @@ #include "encoder/encoderFactory.h" #include "streamServer.h" #include "publishAvahi.h" +#include "config.h" bool g_terminated = false; @@ -53,6 +54,7 @@ int main(int argc, char* argv[]) po::options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message") + ("test", "for testing") ("version,v", "show version number") ("port,p", po::value(&settings.port)->default_value(settings.port), "server port") ("sampleformat,s", po::value(&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::notify(vm); + if (vm.count("test")) + { + Config::instance().test(); + return 1; + } + if (vm.count("help")) { cout << desc << "\n"; diff --git a/server/snapserver.json b/server/snapserver.json new file mode 100644 index 00000000..e056dc64 --- /dev/null +++ b/server/snapserver.json @@ -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 + } + ] +} diff --git a/server/streamServer.cpp b/server/streamServer.cpp index 7f50bf7a..2a1deab3 100644 --- a/server/streamServer.cpp +++ b/server/streamServer.cpp @@ -120,7 +120,7 @@ void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseM { msg::Command commandMsg; commandMsg.deserialize(baseMessage, buffer); - if (commandMsg.command == "startStream") + if (commandMsg.getCommand() == "startStream") { msg::Ack ackMsg; ackMsg.refersTo = commandMsg.id; @@ -132,8 +132,8 @@ void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseM { msg::Hello helloMsg; helloMsg.deserialize(baseMessage, buffer); - connection->macAddress = helloMsg.macAddress; - logO << "Hello from " << connection->macAddress << "\n"; + connection->macAddress = helloMsg.getMacAddress(); + logO << "Hello from " << connection->macAddress << ", host: " << helloMsg.getHostName() << ", v" << helloMsg.getVersion() << "\n"; json j = { {"event", "newConnection"}, {"client", { @@ -142,7 +142,6 @@ void StreamServer::onMessageReceived(ServerSession* connection, const msg::BaseM }} }; controlServer->send(j.dump()); - } }