Github Repo | C Header | C source | JS source |
---|---|---|---|
mongoose-os-libs/rpc-common | mgos_rpc.h | api_rpc.js |
See MG-RPC Guide for detailed documentation.
struct mg_rpc *mg_rpc_create(struct mg_rpc_cfg *cfg);
Create mg_rpc instance. Takes over cfg, which must be heap-allocated.
void mg_rpc_add_channel(struct mg_rpc *c, const struct mg_str dst,
struct mg_rpc_channel *ch);
#define MG_RPC_DST_DEFAULT "*"
Adds a channel to the instance. If dst is empty, it will be learned when first frame arrives from the other end. A "default" channel, if present, will be used for frames that don't have a better match.
void mg_rpc_remove_channel(struct mg_rpc *c, struct mg_rpc_channel *ch);
Remove a channel from the instance.
void mg_rpc_connect(struct mg_rpc *c);
Invokes connect method on all channels of this instance.
void mg_rpc_disconnect(struct mg_rpc *c);
Invokes close method on all channels of this instance.
void mg_rpc_add_local_id(struct mg_rpc *c, const struct mg_str id);
Add a local ID. Frames with this
dst
will be considered addressed to this instance.
typedef void (*mg_result_cb_t)(struct mg_rpc *c, void *cb_arg,
struct mg_rpc_frame_info *fi,
struct mg_str result, int error_code,
struct mg_str error_msg);
Signature of the function that receives response to a request.
bool mg_rpc_callf(struct mg_rpc *c, const struct mg_str method,
mg_result_cb_t cb, void *cb_arg,
const struct mg_rpc_call_opts *opts, const char *args_jsonf,
...);
Make an RPC call. The destination RPC server is specified by
opts
, and destination RPC service name ismethod
.cb
callback function is optional, in which case request is sent but response is not required. opts can be NULL, in which case the default destination is used. Example - calling a remote RPC server over websocket:struct mg_rpc_call_opts opts = {.dst = mg_mk_str("ws://1.2.3.4/foo") }; mg_rpc_callf(mgos_rpc_get_global(), mg_mk_str("My.Func"), NULL, NULL, &opts, "{param1: %Q, param2: %d}", "jaja", 1234);
It is possible to call RPC services running locally. In this case, include the https://github.com/mongoose-os-libs/rpc-loopback library, and use
MGOS_RPC_LOOPBACK_ADDR
special destination address:#include "mg_rpc_channel_loopback.h" struct mg_rpc_call_opts opts = {.dst = mg_mk_str(MGOS_RPC_LOOPBACK_ADDR) };
bool mg_rpc_vcallf(struct mg_rpc *c, const struct mg_str method,
mg_result_cb_t cb, void *cb_arg,
const struct mg_rpc_call_opts *opts, const char *args_jsonf,
va_list ap);
Same as mg_rpc_callf, but takes va_list ap
typedef void (*mg_handler_cb_t)(struct mg_rpc_request_info *ri, void *cb_arg,
struct mg_rpc_frame_info *fi,
struct mg_str args);
Signature of an incoming request handler. Note that only request_info remains valid after return from this function, frame_info and args will be invalidated.
void mg_rpc_add_handler(struct mg_rpc *c, const char *method,
const char *args_fmt, mg_handler_cb_t cb, void *cb_arg);
Add a method handler.
method
can be a pattern, e.g.Foo.*
will match calls toFoo.Bar
. Matching is case-insensitive so invokingfoo.bar
will also work.
typedef bool (*mg_prehandler_cb_t)(struct mg_rpc_request_info *ri, void *cb_arg,
struct mg_rpc_frame_info *fi,
struct mg_str args);
Signature of an incoming requests prehandler, which is called right before calling the actual handler.
If it returns false, the further request processing is not performed. It's called for existing handlers only.
void mg_rpc_set_prehandler(struct mg_rpc *c, mg_prehandler_cb_t cb,
void *cb_arg);
Set a generic method prehandler.
bool mg_rpc_send_responsef(struct mg_rpc_request_info *ri,
const char *result_json_fmt, ...);
Respond to an incoming request. result_json_fmt can be NULL, in which case no result is included.
ri
is freed by the call, so it's illegal to use it afterwards.
bool mg_rpc_send_errorf(struct mg_rpc_request_info *ri, int error_code,
const char *error_msg_fmt, ...);
Send and error response to an incoming request. error_msg_fmt is optional and can be NULL, in which case only code is sent.
ri
is freed by the call, so it's illegal to use it afterwards.
bool mg_rpc_send_error_jsonf(struct mg_rpc_request_info *ri, int error_code,
const char *error_json_fmt, ...);
Like mg_rpc_send_errorf, but uses JSON formatting, see json_printf(). NOTE: "error.message" will still be a string but will contain serialized JSON formatted accordingly to error_json_fmt.
bool mg_rpc_is_connected(struct mg_rpc *c);
Returns true if the instance has an open default channel.
bool mg_rpc_can_send(struct mg_rpc *c);
Returns true if the instance has an open default channel and it's not currently busy.
bool mg_rpc_get_channel_info(struct mg_rpc *c, struct mg_rpc_channel_info **ci,
int *num_ci);
void mg_rpc_channel_info_free(struct mg_rpc_channel_info *ci);
void mg_rpc_channel_info_free_all(struct mg_rpc_channel_info *ci, int num_ci);
Retrieve information about currently active channels. Results are heap-allocated and must be freed all together with mg_rpc_channel_info_free_all() or individuallt with mg_rpc_channel_info_free(). Note: mg_rpc_channel_info_free_all does not free the pointer passed to it.
void mg_rpc_add_list_handler(struct mg_rpc *c);
Enable RPC.List handler that returns a list of all registered endpoints
bool mg_rpc_parse_frame(const struct mg_str f, struct mg_rpc_frame *frame);
Parses frame
f
and stores result intoframe
. Returns true in case of success, false otherwise.
bool mg_rpc_check_digest_auth(struct mg_rpc_request_info *ri);
Checks whether digest auth creds were provided and were correct. After that call, the caller should check whether the authn was successful by checking if
ri->authn_info.username.len
is not empty.If some error has happened, like failure to open
htdigest
file, sends an error response and returns false (in this case,ri
is not valid anymore). Otherwise returns true.NOTE: returned true does not necessarily mean the successful authentication.
RPC.addHandler(name, handler)
Add RPC handler. name
is a string like 'MyMethod'
, handler
is a callback function which takes args
arguments object.
If a handler returns an object with a numeric error
attribute and
optional message
string attribute, the caller will get a failure.
Return value: none.
Example:
RPC.addHandler('Sum', function(args) {
if (typeof(args) === 'object' && typeof(args.a) === 'number' &&
typeof(args.b) === 'number') {
return args.a + args.b;
} else {
return {error: -1, message: 'Bad request. Expected: {"a":N1,"b":N2}'};
}
});
RPC.call(dst, method, args, callback)
Call remote or local RPC service. Return value: true in case of success, false otherwise.
If dst
is empty, connected server is implied. method
is a string
like "MyMethod", callback
is a callback function which takes the following
arguments: res (results object), err_code (0 means success, or error code
otherwise), err_msg (error messasge for non-0 error code), userdata. Example:
RPC.call(RPC.LOCAL, 'Config.Save', {reboot: true}, function (resp, err_code, err_msg, ud) {
if (err_code !== 0) {
print("Error: (" + JSON.stringify(err_code) + ') ' + err_msg);
} else {
print('Result: ' + JSON.stringify(result));
}
}, null);
edit this doc