holding
- specify that the channels in the bridge should be entertained with some media. Channels in the bridge have two possible roles: a participant or an announcer. Media between participant channels is not shared; media from an announcer channel is played to all participant channels.
Depending on the combination of attributes selected when a bridge is created, different mixing technologies may be used for the participants in the bridge. Asterisk will attempt to use the most performant mixing technology that it can based on the channel types in the bridge, subject to the attributes specified when the bridge was created.
Subscription Model
Unlike channels, bridges in a Stasis application are not automatically subscribed to for events. In order to receive events concerning events for a given bridge, the applications resource must be used to subscribe to the bridge via the POST - /applications/{app_name}/subscription
operation. Events related to channels entering and leaving bridges will be sent without the need to subscribe to them since they are related to a channel in a Stasis application.
Example: Interacting with Bridges
For this example, we're going to write an ARI application that will do the following:
- When it connects, it will print out the names of all existing holding bridges. If there are no existing holding bridges, it will create one.
- When a channel enters into its Stasis application, it will be added to the holding bridge and music on hold will be started on the bridge.
Dialplan
The dialplan for this will be very straight forward: a simple extension that drops a channel into Stasis.
Python
For our Python examples, we will rely primarily on the ari-py library. Because the ari
library will emit useful information using Python logging, we should go ahead and set that up as well - for now, a basicConfig
with ERROR
messages displayed should be sufficient. Finally, we'll need to get a client made by initiating a connection to Asterisk. This occurs using the ari.connect
method, where we have to specify three things:
- The HTTP base URI of the Asterisk server to connect to. Here, we assume that this is running on the same machine as the script, and that we're using the default port for Asterisk's HTTP server -
8088
. - The username of the ARI user account to connect as. In this case, we're specifying it as
asterisk
. - The password for the ARI user account. In this case, that's asterisk.
Once we've made our connection, our first task is to look for an existing holding bridge - if there is no existing holding bridge - we need to create it. The bridges resource has an operation for listing existing bridges - GET /bridges
. Using ari-py we need to use the operation nickname - list
. We can then use another bridges resource operation to create a holding bridge if none was found - POST /bridges
. Using ari-py, we need to use the operation nickname - create
.
The GET /channels
operation returns back a list of Bridge
resources. Those resources, however, are returned as JSON from the operation, and while the ari-py
library converts the uniqueid
of those into an attribute on the object, it leaves the rest of them in the JSON dictionary.
Our next step involves adding channels that enter our Stasis application to the bridge we either found or created and signaling when a channel leaves our Stasis application. To do that, we need to subscribe for the StasisStart
and StasisEnd
events:
We need two handler functions - stasis_start_cb
for the StasisStart
event and stasis_end_cb
for the StasisEnd
event:
Finally, we need to tell the client
to run our application. Once we call client.run
, the websocket connection will be made and our application will wait on events infinitely. We can use Ctrl+C
to kill it and break the connection.
bridge-hold.py
The full source code for bridge-hold.py
is shown below:
bridge-hold.py in action
Here, we see the output from the bridge-hold.py
script when a PJSIP channel for endpoint 'alice' enters into the application:
JavaScript (Node.js)
For our JavaScript examples, we will rely primarily on the Node.js ari-client library. We'll need to get a client made by initiating a connection to Asterisk. This occurs using the ari.connect
method, where we have to specify four things:
- The HTTP base URI of the Asterisk server to connect to. Here, we assume that this is running on the same machine as the script, and that we're using the default port for Asterisk's HTTP server -
8088
. - The username of the ARI user account to connect as. In this case, we're specifying it as
asterisk
. - The password for the ARI user account. In this case, that's asterisk.
- A callback that will be called with an error if one occurred, followed by an instance of an ARI client.
Once we've made our connection, our first task is to look for an existing holding bridge - if there is no existing holding bridge - we need to create it. The bridges resource has an operation for listing existing bridges - GET /bridges
. Using ari-client we need to use the operation nickname - list
. We can then use another bridges resource operation to create a holding bridge if none was found - POST /bridges
. Using ari-client, we need to use the operation nickname - create
.
The GET /channels
operation returns back a an error if it occurred and a list of Bridge
resources. ari-client
will return a JavaScript object for each Bridge
resource. Properties such as bridge_type
can be accessed on the object directly.
Our next step involves adding channels that enter our Stasis application to the bridge we either found or created and signaling when a channel leaves our Stasis application. To do that, we need to subscribe for the StasisStart
and StasisEnd
events:
We need two callback functions - stasisStart
for the StasisStart
event and stasisEnd
for the StasisEnd
event:
Finally, we need to tell the client
to start our application. Once we call client.start
, a websocket connection will be established and the client will emit Node.js events as events come in through the websocket. We can use Ctrl+C
to kill it and break the connection.
bridge-hold.js
The full source code for bridge-hold.js
is shown below:
bridge-hold.js in action
Here, we see the output from the bridge-hold.js
script when a PJSIP channel for endpoint 'alice' enters into the application: