Plugin-Gateway communication (implementation) More...
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <inttypes.h>
#include <glib.h>
#include <jansson.h>
Go to the source code of this file.
Data Structures | |
struct | janus_plugin_session |
Plugin-Gateway session mapping. More... | |
struct | janus_plugin |
The plugin session and callbacks interface. More... | |
struct | janus_callbacks |
Callbacks to contact the gateway. More... | |
struct | janus_plugin_result |
Janus plugin result. More... | |
Macros | |
#define | JANUS_PLUGIN_API_VERSION 8 |
Version of the API, to match the one plugins were compiled against. More... | |
#define | JANUS_PLUGIN_INIT(...) |
Initialization of all plugin properties to NULL. More... | |
Typedefs | |
typedef struct janus_callbacks | janus_callbacks |
Callbacks to contact the gateway. More... | |
typedef struct janus_plugin | janus_plugin |
The plugin session and callbacks interface. More... | |
typedef struct janus_plugin_session | janus_plugin_session |
Plugin-Gateway session mapping. More... | |
typedef struct janus_plugin_result | janus_plugin_result |
Result of individual requests passed to plugins. More... | |
typedef janus_plugin * | create_p(void) |
The hook that plugins need to implement to be created from the gateway. More... | |
Janus plugin results | |
When a client sends a message to a plugin (e.g., a request or a command) this is notified to the plugin through a handle_message() callback. The plugin can then either handle the request immediately and provide a response (synchronous approach) or decide to queue it and process it later (asynchronous approach). In both cases the plugin must return a janus_plugin_result instance to the core, that will allow the client to: 1. know whether a response is immediately available or it will be later on through notifications, and 2. what the actual content of the result might be. Of course, notifications related to the transaction may occur later on even for synchronous requests, if the plugin was implemented with use cases that envisage this approach.
| |
enum | janus_plugin_result_type { JANUS_PLUGIN_ERROR = -1, JANUS_PLUGIN_OK, JANUS_PLUGIN_OK_WAIT } |
Result types. More... | |
typedef enum janus_plugin_result_type | janus_plugin_result_type |
Result types. More... | |
janus_plugin_result * | janus_plugin_result_new (janus_plugin_result_type type, const char *text, json_t *content) |
Helper to quickly create a janus_plugin_result instance. More... | |
void | janus_plugin_result_destroy (janus_plugin_result *result) |
Helper to quickly destroy a janus_plugin_result instance. More... | |
Plugin-Gateway communication (implementation)
Plugin-Gateway communication.
Implementation of the janus_plugin_result stuff: all the important things related to the actual plugin API is in plugin.h.
This header contains the definition of the callbacks both the gateway and all the plugins need to implement to interact with each other. The structures to make the communication possible are defined here as well.
In particular, the gateway implements the janus_callbacks
interface. This means that, as a plugin, you can use the methods it exposes to contact the gateway, e.g., in order to have it relay a message, event or RTP/RTCP packet to the peer you're handling. In particular, the methods the gateway exposes to plugins are:
push_event()
: to send a JSON message/event to the peer (with or without an attached JSEP formatted SDP to negotiate a WebRTC PeerConnection); the syntax of the message/event is completely up to you, the only important thing is that it MUST be a JSON object, as it will be included as such within the Janus session/handle protocol;relay_rtp()
: to send/relay the peer an RTP packet;relay_rtcp()
: to send/relay the peer an RTCP message.relay_data()
: to send/relay the peer a SCTP DataChannel message.On the other hand, a plugin that wants to register at the gateway needs to implement the janus_plugin
interface. Besides, as a plugin is a shared object, and as such external to the gateway itself, in order to be dynamically loaded at startup it needs to implement the create_p()
hook as well, that should return a pointer to the plugin instance. This is an example of such a step:
static janus_plugin myplugin = { [..] }; janus_plugin *create(void) { JANUS_LOG(LOG_VERB, , "%s created!\n", MY_PLUGIN_NAME); return &myplugin; }
This will make sure that your plugin is loaded at startup by the gateway, if it is deployed in the proper folder.
As anticipated and described in the above example, a plugin must basically be an instance of the janus_plugin
type. As such, it must implement the following methods and callbacks for the gateway:
init()
: this is called by the gateway as soon as your plugin is started; this is where you should setup your plugin (e.g., static stuff and reading the configuration file);destroy()
: on the other hand, this is called by the gateway when it is shutting down, and your plugin should too;get_api_compatibility()
: this method MUST return JANUS_PLUGIN_API_VERSION;get_version()
: this method should return a numeric version identifier (e.g., 3);get_version_string()
: this method should return a verbose version identifier (e.g., "v1.0.1");get_description()
: this method should return a verbose description of your plugin (e.g., "This is my awesome plugin that does this and that");get_name()
: this method should return a short display name for your plugin (e.g., "My Awesome Plugin");get_package()
: this method should return a unique package identifier for your plugin (e.g., "janus.plugin.myplugin");create_session()
: this method is called by the gateway to create a session between you and a peer;handle_message()
: a callback to notify you the peer sent you a message/request;setup_media()
: a callback to notify you the peer PeerConnection is now ready to be used;incoming_rtp()
: a callback to notify you a peer has sent you a RTP packet;incoming_rtcp()
: a callback to notify you a peer has sent you a RTCP message;incoming_data()
: a callback to notify you a peer has sent you a message on a SCTP DataChannel;slow_link()
: a callback to notify you a peer has sent a lot of NACKs recently, and the media path may be slow;hangup_media()
: a callback to notify you the peer PeerConnection has been closed (e.g., after a DTLS alert);query_session()
: this method is called by the gateway to get plugin-specific info on a session between you and a peer;destroy_session()
: this method is called by the gateway to destroy a session between you and a peer.All the above methods and callbacks, except for incoming_rtp
, incoming_rtcp
, incoming_data
and slow_link
, are mandatory: the Janus core will reject a plugin that doesn't implement any of the mandatory callbacks. The previously mentioned ones, instead, are optional, so you're free to implement only those you care about. If your plugin will not handle any data channel, for instance, it makes sense to not implement the incoming_data
callback at all. At the same time, if your plugin is ONLY going to use data channels and can't care less about RTP or RTCP, incoming_rtp
and incoming_rtcp
can be left out. Finally, slow_link
is just there as a helper, some additional information you may be interested about, but you're not forced to receive it if you don't care.
The gateway janus_callbacks
interface is provided to a plugin, together with the path to the configurations files folder, in the init()
method. This path can be used to read and parse a configuration file for the plugin: the plugins we made available out of the box use the package name as a name for the file (e.g., janus.plugin.echotest.cfg
for the Echo Test plugin), but you're free to use a different one, as long as it doesn't collide with existing ones. Besides, the existing plugins use the same INI format for configuration files the gateway uses (relying on the janus_config
helpers for the purpose) but again, if you prefer a different format (XML, JSON, etc.) that's up to you.
Both the the gateway and a plugin can have several different sessions with the same and/or different peers: to match a specific session, a plugin can rely on a mapping called janus_plugin_session that is what all the communication between the plugins and the gateway (that is, both methods invoked by the gateway and callbacks invoked by the plugins) will make use of. See the janus_videoroom.c plugin for an example of multiple handles associated to the same peer.
All messages/requests/events sent to and received from a plugin are asynchronous, meaning there's no way to immediately reply to a message sent by a browser, for instance. Messages/requests coming from browsers in a handle_message()
callback, though, have a transaction identifier, which you can use in a push_event()
reply to allow the browser to match it to the original request, if needed.
As anticipated, both handle_message()
and push_event()
can attach a JSEP/SDP payload. This means that a browser, for instance, can attach a JSEP/SDP offer to negotiate a WebRTC PeerConnection with a plugin: the plugin would then need to provide, immediately or not, a JSEP/SDP answer to do so. At the same time, a plugin may want to originate the call instead: in that case, the plugin would attach a JSEP/SDP offer in a push_event()
call, to which the browser would then need to reply with a JSEP/SDP answer, as described in JavaScript API.
#define JANUS_PLUGIN_API_VERSION 8 |
Version of the API, to match the one plugins were compiled against.
#define JANUS_PLUGIN_INIT | ( | ... | ) |
Initialization of all plugin properties to NULL.
static janus_plugin janus_echotest_plugin = { JANUS_PLUGIN_INIT, .init = janus_echotest_init, [..]
typedef janus_plugin* create_p(void) |
The hook that plugins need to implement to be created from the gateway.
typedef struct janus_callbacks janus_callbacks |
Callbacks to contact the gateway.
typedef struct janus_plugin janus_plugin |
The plugin session and callbacks interface.
typedef struct janus_plugin_result janus_plugin_result |
Result of individual requests passed to plugins.
typedef enum janus_plugin_result_type janus_plugin_result_type |
Result types.
typedef struct janus_plugin_session janus_plugin_session |
Plugin-Gateway session mapping.
Result types.
void janus_plugin_result_destroy | ( | janus_plugin_result * | result | ) |
Helper to quickly destroy a janus_plugin_result instance.
[in] | result | The janus_plugin_result instance to destroy |
[in] | result | The janus_plugin_result instance to destroy |
janus_plugin_result* janus_plugin_result_new | ( | janus_plugin_result_type | type, |
const char * | text, | ||
json_t * | content | ||
) |
Helper to quickly create a janus_plugin_result instance.
[in] | type | The type of result |
[in] | text | String to add to the result (for JANUS_PLUGIN_OK_WAIT or JANUS_PLUGIN_ERROR), if any |
[in] | content | The json_t object with the content of the result, if any |