43#if FL_PLATFORM_HAS_LARGE_MEMORY
70 FL_ERROR(
"RPC: Invalid Request - missing 'method' field");
74 auto methodOpt = request[
"method"].
as_string();
75 if (!methodOpt.has_value()) {
76 FL_ERROR(
"RPC: Invalid Request - 'method' must be a string");
81#if FL_PLATFORM_HAS_LARGE_MEMORY
88 if (methodName ==
"rpc.discover") {
90 response.set(
"jsonrpc",
"2.0");
91 response.set(
"result",
schema());
93 response.set(
"id", request[
"id"]);
102 FL_WARN(
"RPC: Method not found: " << methodName.
c_str());
109 FL_ERROR(
"RPC: Invalid params - must be an array for method: " << methodName.
c_str());
123 ack.
set(
"jsonrpc",
"2.0");
124 ack.
set(
"id", request[
"id"]);
127 ackResult.
set(
"acknowledged",
true);
128 ack.
set(
"result", ackResult);
131 FL_DBG(
"RPC: Sent ACK for async method: " << methodName.
c_str());
137 if (isResponseAware) {
149 resultTuple = entry.
mInvoker->invoke(params);
156 if (!convResult.
ok()) {
163 response.set(
"jsonrpc",
"2.0");
164 response.set(
"result", returnVal);
168 response.set(
"id", request[
"id"]);
174 for (fl::size i = 0; i < convResult.
warnings().size(); ++i) {
177 response.set(
"warnings", warnings);
182 response.set(
"__async",
true);
197 auto methodOpt = request[
"method"].
as_string();
198 if (methodOpt.has_value()) {
204 it->second.mInvoker->invoke(params);
222 for (fl::size i = 0; i < it->second.mTags.size(); ++i) {
224 for (fl::size j = 0; j <
result.size(); ++j) {
225 if (
result[j] == it->second.mTags[i]) {
231 result.push_back(it->second.mTags[i]);
247 methodTuple.
push_back(it->first.c_str());
248 methodTuple.
push_back(it->second.mSchemaGenerator->resultTypeName());
249 methodTuple.
push_back(it->second.mSchemaGenerator->params());
252 const char* modeStr = (it->second.mMode ==
RpcMode::ASYNC) ?
"async" :
"sync";
Helper class for sending responses in async/streaming RPC methods.
void setResponseSink(fl::function< void(const fl::json &)> sink)
Set response sink for sending ACK responses (used by async functions)
fl::unordered_map< fl::string, detail::RpcEntry > mRegistry
json handle(const json &request)
Process a JSON-RPC request.
fl::vector< fl::string > tags() const
Returns list of unique tags used across all methods.
fl::function< void(const fl::json &)> mResponseSink
json schema() const
Returns flat schema document.
fl::optional< json > handle_maybe(const json &request)
For notifications (no id), returns nullopt.
json methods() const
Returns flat method array: [["name", "returnType", [["param1", "type1"], ...]], .....
void bindAsync(const char *name, fl::function< void(ResponseSend &, const json &)> fn, fl::RpcMode mode=fl::RpcMode::ASYNC)
Bind async method with ResponseSend& parameter (for ASYNC/ASYNC_STREAM modes) Signature: void(Respons...
const fl::string & errorMessage() const
const fl::vector< fl::string > & warnings() const
static TypeConversionResult success()
const char * c_str() const FL_NOEXCEPT
void push_back(const json &value) FL_NOEXCEPT
bool is_array() const FL_NOEXCEPT
bool contains(size_t idx) const FL_NOEXCEPT
fl::optional< fl::string > as_string() const FL_NOEXCEPT
void set(const fl::string &key, const json &value) FL_NOEXCEPT
static json parse(const fl::string &txt) FL_NOEXCEPT
static json object() FL_NOEXCEPT
static json array() FL_NOEXCEPT
FastLED's Elegant JSON Library: fl::json
Centralized logging categories for FastLED hardware interfaces and subsystems.
json makeJsonRpcError(int code, const fl::string &message, const json &id)
fl::shared_ptr< ErasedInvoker > mInvoker
fl::function< void(ResponseSend &, const json &)> mResponseAwareFn
fl::shared_ptr< ErasedSchemaGenerator > mSchemaGenerator
fl::vector< fl::string > mTags
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
tuple< typename fl::decay< Ts >::type... > make_tuple(Ts &&... args) FL_NOEXCEPT
expected< T, E > result
Alias for expected (Rust-style naming)
constexpr nullopt_t nullopt
auto invoke(F &&f, T1 &&t1, Args &&... args) FL_NOEXCEPT -> enable_if_t< is_member_function_pointer< typename remove_reference< F >::type >::value &&!detail::use_pointer_syntax< T1 >::value, decltype((fl::forward< T1 >(t1).*f)(fl::forward< Args >(args)...))>
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) FL_NOEXCEPT
Base definition for an LED controller.