ARI v0.1.2 ARI.Stasis behaviour View Source
The ARI.Stasis
module is used to register a Stasis application with the Asterisk server. It connects to the Asterisk server using a websocket.
The host, username and password are configured in the Asterisk configuration file ari.conf. The name that is registered is provided in the ARI.Stasis.app_config/0
as name
.
Once registered it receives all events for all channels associated with a Stasis application. Here's an example application, you can see the Stasis app configured for the built-in ARI.Router
application as well as a custom application, in the list of children.
Example
defmodule ExARIExample.Application do
use Application
alias ARI.{ChannelRegistrar, Configurator, HTTP, Stasis}
def start(_, _) do
un = System.get_env("ASTERISK_USERNAME")
pw = System.get_env("ASTERISK_PASSWORD")
ws_host = System.get_env("ASTERISK_WS_HOST")
rest_host = System.get_env("ASTERISK_REST_HOST")
rest_port = System.get_env("ASTERISK_REST_PORT") |> String.to_integer()
name = System.get_env("ASTERISK_NAME")
transport = System.get_env("ASTERISK_TRANSPORT")
context = System.get_env("ASTERISK_CONTEXT")
channel_supervisor = ExARIExample.ChannelSupervisor
config_module = ExARIExample.Config
client_config = %{name: "ex_ari", module: ExARIExample.Client}
router_config = %{
name: "router",
module: ARI.Router,
extensions: %{
"ex_ari" => "ex_ari",
"+15555550101" => "ex_ari"
}
}
children = [
ChannelRegistrar,
{DynamicSupervisor, strategy: :one_for_one, name: channel_supervisor},
{HTTP.Asterisk, [rest_host, rest_port, un, pw]},
{HTTP.Channels, [rest_host, rest_port, un, pw]},
{HTTP.Playbacks, [rest_host, rest_port, un, pw]},
{Stasis, [channel_supervisor, client_config, ws_host, un, pw]},
{Stasis, [channel_supervisor, router_config, ws_host, un, pw]},
{Configurator, [name, transport, context, config_module]},
]
opts = [strategy: :one_for_one, name: ExARIExample.Supervisor]
Supervisor.start_link(children, opts)
end
end
Using this example, all calls to +15555550101
will have a ExARIExample.Client
process spawned and subsequent call events will be passed to the indivdual process. More explicitly, each call has a unique process spawned that is supervised by the DynamicSupervisor passed to ARI.Stasis
.
For the full example check out the ex_ari_example application, which will get you up and running with making calls on your local machine.
There are two very important events that ARI.Stasis
receives that drive an ex_ari
application StasisStart
and StasisEnd
.
StasisStart
When a StasisStart event is received it will spawn a new process under the supervisor provided as the channel_supervisor
, this needs to be a DynamicSupervisor
, to the ARI.Stasis.start_link/5
function. The process that is spawned is provided in the ARI.Stasis.app_config/0
as the module
.
Before actually spawning the app process the WebSocket process will call the function state/5
on the app module with the id of the incoming channel, the caller id (a string of the number that is calling), a list of any arguments passed to the application (an empty list for standard stasis applications), the initial StasisStart event and the ARI.Stasis.app_config/0
that was passed to the ARI.Stasis
module on startup. The ARI.Router
application provided with ex_ari
makes special use of the ARI.Stasis.app_config/0
by pulling extensions from the config to route incoming calls to their respective applications. The state/5
behaviour function is expected to return ARI.Stasis.channel_state/0
a struct or map containing at a minimum :channel
, :caller
and :start_event
keys populated with the data passed to the state/5
function. The rest of the keys can be whatever is needed by your application. This data is then passed to the GenServer.start_link/2
function of your app module in the form [state]
and should be used as your processes state for the lifetime of the process.
To map channel ids to pids there is an Agent process that maintains the mappings, ARI.ChannelRegistrar
. This is provided by the ex_ari
library, but needs to be explicitly started by your application.
StasisEnd
Upon receiving a StasisEnd event the ARI.Stasis
module will begin tearing down the process associated with the channel id. It kills the process by calling DynamicSupervisor.terminate_child/3
and deregistering the pid from the ARI.ChannelRegistrar
Agent process.
Other Events
The ARI.Stasis
process does its best to extract out the channel id from several different types of events in order to route the event to the correct process. All events are sent using send/2
in the form of {:ari, event}
where event is the JSON event deserialized with atom keys. Events that are not routable are handled with a Logger.warn/1
message.
Link to this section Summary
Callbacks
Called when an incoming call is received.
Arguments are Channel ID
, Caller ID
, Args
, StasisStart Event
and App Config
Link to this section Types
Link to this section Functions
Link to this section Callbacks
Called when an incoming call is received.
Arguments are Channel ID
, Caller ID
, Args
, StasisStart Event
and App Config