Loading...
Searching...
No Matches
Event handlers documentation

Controlling and monitoring a Janus instance can be done using the Admin/Monitor API which includes ways to query information related to the state of ongoing PeerConnections (ICE/DTLS state, stats, etc.). That said, while powerful and useful the Admin API is a poll-based protocol: this means that you have to query for information yourself, and if you want to keep up-to-date with what is happening, you have to do that on a regular basis. As such, things can get problematic when dealing with many sessions and handles running in your application, as you may not be immediately aware of which session/handle corresponds to what, or which of them belong to the same scenario (e.g., all PeerConnections established in the context of the same VideoRoom).

This is where Event Handlers can help. Just like media and transport plugins, Event Handlers plugins in Janus themselves, meaning their modular nature allows for extensibility. When enabling Event handlers, Janus and other plugins generate real-time events related to several different aspects that may be happening during its lifetime: these events are then passed to all the available event handler plugins, plugins that can then decide to do with these events whatever they want. They might choose to store these events somehow, aggregate, dump or process them, format and send them to an external application, and so on. This really depends on what these events should be used for.

Janus will generate events related to:

- session related events (e.g., session created/destroyed, etc.);
- handle related events (e.g., handle attached/detached, etc.);
- JSEP related events (e.g., got/sent offer/answer);
- WebRTC related events (e.g., PeerConnection up/down, ICE updates, DTLS updates, etc.);
- media related events (e.g., media started/stopped flowing, stats on packets/bytes, etc.);
- generic events originated by the Janus core (e.g., Janus started/stopped);
- events originated by plugins (content specific plugins themselves);
- events originated by transports (see above);
- events originated by external applications via the Admin API (content specific to source).

# Events format

All events generated by Janus are JSON object, which have a shared header and a custom body that will depend on the type (and in some cases subtype) of the event itself.

The header of the event will contain some information that is usually common to all events: this includes `type` and (when needed) `subtype` of the event, a timestamp in microseconds (so that you can know exactly when the event was generated in the first place from the server's perspective, no matter it was received), and various IDs. These IDs include the session identifier (Janus session the event refers to), the handle identifier (Janus handle the event refers to) and an opaque ID (set by whoever controls the Janus API): as we'll see, all these IDs are optional, as there are events that are not related to a session in particular (e.g., a server shutdown event), but can be very important for correlation purposes when they're used.

The generic format of events is the following:

        {
            "emitter" : "<string identifying the source of the event, if configured (optional)>",
            "type" : <numeric event type identifier>,
            "subtype" : <numeric event subtype identifier (specific to the event type; optional)>,
            "timestamp" : <time of when the event was generated>,
            "session_id" : <unique session identifier, if provided/available (optional)>,
            "handle_id" : <unique handle identifier, if provided/available (optional)>,
            "opaque_id" : "<user-provided opaque identifier, if provided/available (optional)>",
            "event" : {
                 <event body, custom depending on event type>
            }
        }

For instance, this is what an event related to a new session being created would look like:

        {
            "emitter": "MyJanusInstance",
            "type": 1,
            "timestamp": 1582211094846980,
            "session_id": 3439056127855429,
            "event": {
                "name": "created",
                "transport": {
                    "transport": "janus.transport.http",
                    "id": "0x60400002c2d0"
                }
            }
        }

Since `type` `1` is related to session events, this event basically tells us that a new session with ID `3439056127855429` was created (we know this from the `name` property in the event body) on the Janus instance called `MyJanusInstance` at the timestamp `1582211094846980` . There are no `subtype` , `handle_id` or `opaque_id` properties as they were unneeded or not applicable here.

# Event types

As we've seen from the previous example, event types are numeric. In order to figure out what you're receiving, you can refer to the following table as a reference:

Type | Category of event
--- | ---
1 | Session related event
2 | Handle related event
4 | External event (injected via Admin API)
8 | JSEP event (SDP offer/answer)
16 | WebRTC state event (ICE/DTLS states, candidates, etc.)
32 | Media event (media state, reports, etc.)
64 | Plugin-originated event (e.g., event coming from VideoRoom)
128 | Transport-originated event (e.g., WebSocket connection state)
256 | Core event (server startup/shutdown)

The types of events are not monotonically increasing as, internally, they're represented as a mask: this allows event handler plugins to only subscribe to a subset of them, rather than them all, when needed.

The event `type` property dictates the syntax of the `event` body , meaning that the body for a JSEP event (type `8` ) will for instance be very different from a media event (type `32` ). That said, the format of some events can change even within the same type: for instance, a WebRTC state event includes a lot of different notifications, including ICE states, DTLS states, local and remote candidates, selected pair, etc. In order to allow event handler recipients written in strongly typed languages to be able to use different classes for the different events, a different property called `subtype` can help further discriminate an event of a specified `type`. At the time of writing, a `subtype` attribute will only be present if the event is of type `256` (core), `16` (WebRTC) and `32` (media): all other event types have a consistent format, and so don't need this differentiation (e.g., type `8` includes both SDP offers and answers, but the nature of the SDP is indicated in an attribute that has the same name in both cases).

The available subtypes are the following:

Core subtype
1 | Server startup
2 | Server shutdown
WebRTC subtype
1 | ICE state
2 | Local candidate
3 | Remote candidate
4 | Selected pair
5 | DTLS state
6 | PeerConnection state
Media subtype
1 | Medium state
2 | Slow link
3 | Report/stats