Login | Register

Documentation

Documentation -> Tutorials -> Event Interface 1.8

This page has been visited 5873 times.


This tutorial is for OpenSIPS 1.8.x version

1.  Event Interface

The OpenSIPS Event Interface provides an easy way to notify external applications whenever certain events occur inside OpenSIPS. Basically it provides two interfaces: one for the OpenSIPS internal modules and core, that is used to advertise and raise events, and an interface for the external applications, allowing them to register for specific events, and notifying them when those events are triggered by the modules, core, or by the OpenSIPS script.


2.  Overview

OpenSIPS can notify an external application using different transport protocols:

In order to receive an event notification, an external application has to subscribe for a specific event to the Event interface. This can be done either using an MI command, or can be done directly from the OpenSIPS script. The subscription command has to specify the event that the external application wants to register to, and a socket where the notification has to be sent. The format of the socket is different, depending on the transport module used (you can find more information about this in the module's documentation page).

When an event is triggered, the Event Interface will send to each application that is subscribed for that event a notification, using the desired transport type. The event details are packed differently for each transport module (consult the transport module's documentation page for more details).


3.  Event Subscription

As mentioned above, an external application can subscribe for an event either using MI, or directly from OpenSIPS script. In the next sections we will describe the use case of each of them.

3.1  MI Subscription

An external application should subscribe for an event using MI commands when the subscription nature is very dynamic: it subscribes for a short period, receives notifications, then decides to unsubscribe and so on. The MI function used to subscribe for an event is event_subscribe.

For example, to subscribe for the E_PIKE_BLOCKED event for only 1200 seconds, an external application that listens on localhost, UDP port 8888, has to issue the following MI command:

   $ opensipsctl fifo event_subscribe E_PIKE_BLOCKED udp:127.0.0.1:8888 1200

The first parameter is the name of the event (see here), the second parameter is the listening socket name (the format depends on the transport module used) and the last parameter is the expiration period expressed in seconds. Note that if the last parameter is missing, a default subscription period of 3600s (1h) is assumed.

In order to unsubscribe for an event, the external application has to use the same event and socket used at subscription time, but specify an expiration time of 0. The following command unsubscribes the previously registered application.

   $ opensipsctl fifo event_subscribe E_PIKE_BLOCKED udp:127.0.0.1:8888 0

3.2  Script Subscription

The Event Interface allows the script writer to subscribe for an event directly from the OpenSIPS configuration script. This is usually used when a subscription is permanent, that never expires. For example a server that is continuously listening from events from OpenSIPS and process them accordingly. The command used to subscribe for an event from script is subscribe_event.

Usually these kind of subscriptions are permanent, therefore they should be registered at when OpenSIPS starts. Therefore this should be done in startup_route, but this is not a requirement, as the function can be used in any route.

Here is an example of subscription for the E_PIKE_BLOCKED event at OpenSIPS startup, without any expire time, from the OpenSIPS configuration script:

   startup_route() {
      subscribe_event("E_PIKE_BLOCKED", "udp:127.0.0.1:8888");
   }

If the script writer wants the subscription to expire after 1200 second, the third parameter of the subscribe_event function can be specified:

   timer_route[event_subscribe,3600] {
      subscribe_event("E_PIKE_BLOCKED", "udp:127.0.0.1:8888", 1200);
   }

4.  Events

There are two types of events: static/predefined events, exported by OpenSIPS code and modules, and documented by each module, and dynamic events that can be raised by the script writer directly from the script. A few examples of predefined events:

  • E_PIKE_BLOCKED - raised when pike module decides an IP should be blocked.
  • E_RTPPROXY_STATUS - raised when a RTPProxy connects or disconnects.
  • E_DISPATCHER_STATUS - raised by the dispatcher module when a destination address becomes active/inactive.
  • E_CORE_THRESHOLD - raised when using debugging bottleneck detection and the limit is exceeded.

4.1  Events Name

Although there is not a strict events naming imposed by the Event Interface, it is a good practice for an event's name to follow the format E_MODULE_NAME, where MODULE is the name of the module that exports the event, CORE if the event is exported by OpenSIPS core, and SCRIPT if it is a dynamic event raised from the script, and NAME is the name of the event.

4.2  Raising an Event

In order to raise an event from the script, the raise_event function has to be used. The function receives one, two or three parameters, depending on the script writer needs. If the event has no parameters, then only the first parameter is needed - the event's name.

If the script writer wants to attach some extra information to the event, then the second and optionally the third parameter has to be used. The extra information has to be stored in an AVP as values, for example:

    $avp(values) = "value1";
    $avp(values) = "value2";
    ...

If the parameters also have some names, then a new AVP have to store them. Note that the number of values in the first AVP has to be the same as in the one for the attributes:

    $avp(attributes) = "param1";
    $avp(values) = "value1";
    $avp(attributes) = "param2";
    $avp(values) = "value2";
    ...

In order to raise the event from the script, the following code has to be used:

   raise_event("E_SCRIPT_EVENT");     # raises an event without any parameters

   raise_event("E_SCRIPT_EVENT", $avp(values));     # raises an event that has only values parameters

   raise_event("E_SCRIPT_EVENT", $avp(attributes), $avp(values));     # raises an event with multiple attribute-value pairs

4.3  Example

A practical use case of dynamic events is raising an event from the script when the TCP load is greater than 80%:

   route[TCP_LOAD_CHECK] {

      if ($stat(tcp-load) > 80) {
         # raise the event, specifying the limit and the real load
         $avp(attrs) = "limit";
         $avp(vals) = 80;
         $avp(attrs) = "load";
         $avp(vals) = $stat(tcp-load);

         raise_event("E_SCRIPT_TCP_LOAD", $avp(attrs), $avp(vals));
      }
   }

5.  Transport Modules

There are several transport modules that can be used to notify an external application. At the time this tutorial was written, the following transport methods were supported:

5.1  Datagram Messages

External applications can be notified when OpenSIPS internal events are triggered using either UDP or UNIX datagrams. This allows programmers to write a simple UDP server that receives the notification and process it in the preferred programming language.

In order to support this type of communication, the event_datagram module has to be loaded. Consult the module's documentation page for more information about subscription socket and encapsulation format.

5.2  RabbitMQ Messages

OpenSIPS can also communicate with a RabbitMQ server using the AMQP (Advanced Message Queuing Protocol) messages. This type of communication leverages all the features the queuing server has.

The event_rabbitmq module provides this functionality. Note that in this case, the "external application" is the RabbitMQ server, so you do not have the possibility to subscribe for events from it. Therefore the programmer should either use a different application to subscribe for the event, or subscribes for it directly from the OpenSIPS script (as discussed here). For more information please visit the module's documentation page.


Page last modified on May 16, 2013, at 07:04 PM