You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/Configuration/Channel-Drivers/WebSocket.md
+33-35Lines changed: 33 additions & 35 deletions
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ Outgoing connections require you to pre-configure a websocket client in the `web
29
29
exten = _x.,1,Dial(WebSocket/connection1/c(ulaw))
30
30
```
31
31
32
-
This would connect to your application's websocket server using the client named `connection1` and using the `ulaw` codec. Right after your server accepts the connection, you'll get a TEXT websocket message `MEDIA_START connection_id:<connection_id> channel:<channel_name> optimal_frame_size:<optimal_frame_size>`. This will allow you to correlate the incoming connection to the specific channel. The `a` dialstring options tells the channel driver to auto-answer the channel on successful connection. If you omit the `a`, you can send an `ANSWER` TEXT message to answer the channel yourself.
32
+
This would connect to your application's websocket server using the client named `connection1` and using the `ulaw` codec. Right after your server accepts the connection, you'll get a TEXT websocket message `MEDIA_START connection_id:<connection_id> channel:<channel_name> optimal_frame_size:<optimal_frame_size>`. This will allow you to correlate the incoming connection to the specific channel.
33
33
34
34
### Incoming Connections
35
35
@@ -40,9 +40,9 @@ Incoming connections must be made to the global Asterisk HTTP server using the `
40
40
exten = _x.,1,Dial(WebSocket/INCOMING/c(ulaw)n)
41
41
```
42
42
43
-
The websocket channel will be created immediately and the `MEDIA_WEBSOCKET_CONNECTION_ID` channel variable will be set to an ephemeral connection id which must be used in the URI your application will connect to Asterisk with. For example `/media/32966726-4388-456b-a333-fdf5dbecc60d`. When Asterisk accepts the connection, you'll see the same `MEDIA_START` message as above. You can also omit the `a` option and send an `ANSWER` TEXT message as above.
43
+
The websocket channel will be created immediately and the `MEDIA_WEBSOCKET_CONNECTION_ID` channel variable will be set to an ephemeral connection id which must be used in the URI your application will connect to Asterisk with. For example `/media/32966726-4388-456b-a333-fdf5dbecc60d`. When Asterisk accepts the connection, you'll see the same `MEDIA_START` message as above.
44
44
45
-
The default behavior is to automatically answer the channel when the websocket has connected successfully. If for some reason you want to answer the channel yourself, you can add the `n` parameter to the dialstring and make a REST `channels/<id>/answer` call or send the `ANSWER` command (mentioned below) over the media websocket.
45
+
Whether inbound or outbound, the default behavior is to automatically answer the channel when the websocket has connected successfully. If for some reason you want to answer the channel yourself, you can add the `n` parameter to the dialstring and make a REST `channels/<id>/answer` call or send the `ANSWER` command (mentioned below) over the media websocket.
46
46
47
47
## Protocol
48
48
@@ -54,13 +54,13 @@ Media sent _to_ Asterisk _from_ your app is a bit trickier because chances are t
54
54
55
55
When the websocket channel is created, a `MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE` channel variable will be set that tells you the amount of data Asterisk needs to create a good 20ms frame using the codec you specified in the dialstring. This is also reported in the `MEDIA_START` TEXT message. If you send a websocket message with a length that's exactly that size or some even multiple of that size, the channel driver will happily break that message up into the correctly sized frames and send one frame to the Asterisk core every 20ms with no leftover data. If you send an oddly sized message though, the extra data that won't fill a frame will be dropped. However...
56
56
57
-
If you need to send a file or a buffer received from an external source like an AI agent, it's quite possible that the buffer size won't be an even multiple of the optimal size. In this case, the app can send Asterisk a `START_BULK_MEDIA` TEXT websocket message before sending the media. This tells the channel driver to buffer the data received so it can make full frames even across multiple received BINARY messages. That process will continue until the app sends Asterisk a `END_BULK_MEDIA` TEXT message. When the channel driver receives that, it'll take whatever data is left in the buffer that couldn't make a full frame and append silence to it to make up a full frame and send that to the core.
57
+
If you need to send a file or a buffer received from an external source like an AI agent or a file, it's quite possible that the buffer size won't be an even multiple of the optimal size. In this case, the app can send Asterisk a `START_MEDIA_BUFFERING` TEXT websocket message before sending the media. This tells the channel driver to buffer the data received so it can make full frames even across multiple received BINARY messages. That process will continue until the app sends Asterisk a `STOP_MEDIA_BUFFERING` TEXT message. When the channel driver receives that, it'll take whatever data is left in the buffer that couldn't make a full frame with, append silence to it to make up a full frame and send that to the core.
58
58
59
59
So why can't Asterisk just do that process all the time and dispense with the TEXT messages? Well, let's say the app sends a message with an odd amount of data and the channel driver saves off the odd bit. What happens if you don't send any data for a while? If 20ms goes by and the channel driver doesn't get any more data what is it supposed to do with the leftover? If it appends silence to make a full frame and sends it to the core, then the app sends more data after 30ms, the caller will hear a gap in the audio. If the app does that a lot, it'll be a bad experience for ther caller.
60
60
61
61
### Max Message Size and Flow Control
62
62
63
-
Chances are that your app will be sending data faster to Asterisk than Asterisk will be sending out to a caller so there are some rules you need to follow to prevent the channel driver from consuming excessive memory...
63
+
Chances are that your app will be sending data faster to Asterisk than Asterisk will be sending out to a caller so there are some rules you need to follow to prevent the channel driver from consuming excessive memory. First...
64
64
65
65
/// warning
66
66
The maximum websocket message size the underlying websocket code can handle is 65500 bytes. Attempting to send a message greater than that length will result in the websocket being closed and the call hungup!
@@ -74,50 +74,48 @@ See the next section for more commands the app can send.
74
74
75
75
/// warning
76
76
You must ensure that the control messages are sent as TEXT messages. Sending them as BINARY messages will cause them to be treated as media.
77
+
78
+
All commands are case-sensitive.
77
79
///
78
80
79
81
Some of the control TEXT messages you can send the driver have already been mentioned but here's the full list:
80
82
81
83
#### Commands
82
84
83
-
/// note
84
-
All commands are case-sensitive.
85
-
///
86
-
87
85
/// define
88
-
`ANSWER`: Answer the WebSocket channel
86
+
`ANSWER`
89
87
90
88
- This will cause the WebSocket channel to be answered.
91
89
92
-
`HANGUP`: Hangup the WebSocket channel
90
+
`HANGUP`
93
91
94
92
- This will cause the WebSocket channel to be hung up and the websocket to be closed.
95
93
96
-
`START_BULK_MEDIA`: Start buffering media
94
+
`START_MEDIA_BUFFERING`
97
95
98
96
- Indicates to the channel driver that the following media should be buffered to create properly sized and timed frames.
99
97
100
-
`END_BULK_MEDIA <optional_id>`: Stop buffering media
98
+
`STOP_MEDIA_BUFFERING <optional_id>`
101
99
102
-
- Indicates to the channel driver that buffering is no longer needed and anything remaining in the buffer should have silence appended before sending to the Asterisk core. When the last frame of this bulk transfer has been sent to the core, the app will receive a `BULK_MEDIA_END` notification. If the optional id was specified in this command, it'll be returned in the notification. If you send multiple files in quick succession, the id can help you correlate the `BULK_MEDIA_END` notification to the `END_BULK_MEDIA` command that trigfgered it.
100
+
- Indicates to the channel driver that buffering is no longer needed and anything remaining in the buffer should have silence appended before sending to the Asterisk core. When the last frame of this bulk transfer has been sent to the core, the app will receive a `MEDIA_BUFFERING_COMPLETED` notification. If the optional id was specified in this command, it'll be returned in the notification. If you send multiple files in quick succession, the id can help you correlate the `MEDIA_BUFFERING_COMPLETED` notification to the `STOP_MEDIA_BUFFERING` command that triggered it.
103
101
104
-
`PAUSE_MEDIA`: Pause media being sent to the Asterisk core
102
+
`FLUSH_MEDIA`
105
103
106
-
-If you've sent a large amount of media but need to pause it playing to a caller while you decide if you need to flush it or not, you can send a `PAUSE_MEDIA` command. The channel driver will then start playing silence to the caller but keep the data you've already sent in the queue. You can still send media to the channel driver while it's paused; it just will get queued behind whatever was already in the queue.
104
+
-Send this command to the channel driver if you've sent a large amount of media but want to discard any queued but not sent. Flushing the buffer automatically ends any bulk transfer in progress and also resets the paused state so there's no need to send `STOP_MEDIA_BUFFERING` or `CONTINUE_MEDIA` commands. No `MEDIA_BUFFERING_COMPLETED` notification will be sent in this case. This command could be useful if an automated agent detects the caller is speaking and wants to interrupt a prompt it already replied with.
107
105
108
-
`CONTINUE_MEDIA`: Continue media being sent to the Asterisk core
106
+
`PAUSE_MEDIA`
109
107
110
-
- If you've previously paused the media, this will cause the channel driver to stop playing silence and resume playing media from the queue from the point you paused it.
108
+
- If you've sent a large amount of media but need to pause it playing to a caller while you decide if you need to flush it or not, you can send a `PAUSE_MEDIA` command. The channel driver will then start playing silence to the caller but keep the data you've already sent in the queue. You can still send media to the channel driver while it's paused; it'll just get queued behind whatever was already in the queue.
111
109
112
-
`FLUSH_MEDIA`: Flush the buffer
110
+
`CONTINUE_MEDIA`
113
111
114
-
-Send this command to the channel driver if you've sent a large amount of media but want to discard any queued but not sent. Flushing the buffer automatically ends any bulk transfer in progress and also resets the paused state so there's no need to send `END_BULK_MEDIA` or `CONTINUE_MEDIA` commands. No `BULK_MEDIA_END` notification will be sent in this case. This command could be useful if an automated agent detects the caller is speaking and wants to interrupt a prompt it already replied with.
112
+
-If you've previously paused the media, this will cause the channel driver to stop playing silence and resume playing media from the queue from the point you paused it.
115
113
116
-
`GET_STATUS`: Get the current queue status
114
+
`GET_STATUS`
117
115
118
116
- This will cause the channel driver to send back a `STATUS` message (described below).
119
117
120
-
`REPORT_QUEUE_DRAINED`: Request a notification when the frame queue is empty
118
+
`REPORT_QUEUE_DRAINED`
121
119
122
120
- This will cause the channel driver to send back a one-time `QUEUE_DRAINED` notification the next time it detects that there are no more frames to process in the queue.
123
121
@@ -127,23 +125,23 @@ All commands are case-sensitive.
127
125
128
126
/// define
129
127
130
-
`MEDIA_XOFF`: Stop sending media
128
+
`MEDIA_XOFF`
131
129
132
-
- The channel driver will send this notification to the app when the frame queue length reaches the high water mark. The app should then pause sending media. Any media sent after this has a high probability of being dropped.
130
+
- The channel driver will send this notification to the app when the frame queue length reaches the high water (XOFF) level. The app should then pause sending media. Any media sent after this has a high probability of being dropped.
133
131
134
-
`MEDIA_XON`: Start sending media again
132
+
`MEDIA_XON`
135
133
136
-
- The channel driver will send this notification when the frame queue length drops below the low water mark. This indicates that it's safe for the app to start sending media again.
134
+
- The channel driver will send this notification when the frame queue length drops below the low water (XON) level. This indicates that it's safe for the app to start sending media again.
137
135
138
-
`STATUS`: Response from the `GET_STATUS` command
136
+
`STATUS`
139
137
140
138
- The channel driver will send this notification in response to a `GET_STATUS` command.<br>Example: `STATUS queue_length:43 xon_level:800 xoff_level:900 queue_full:false bulk_media:true media_paused:false`
141
139
142
-
`BULK_MEDIA_END [ <optional_id> ]`: Indicates that a bulk media transfer has finished.
140
+
`MEDIA_BUFFERING_COMPLETED [ <optional_id> ]`
143
141
144
-
- The channel driver will send this mesage when bulk media has finished being framed, timed and sent to the Asterisk core. If an optional id was supplied on the `END_BULK_XFER` command, it will be returned in this message.
142
+
- The channel driver will send this mesage when bulk media has finished being framed, timed and sent to the Asterisk core. If an optional id was supplied on the `STOP_MEDIA_BUFFERING` command, it will be returned in this message.
145
143
146
-
`QUEUE_DRAINED`: Response from `REPORT_QUEUE_DRAINED`
144
+
`QUEUE_DRAINED`
147
145
148
146
- The channel driver will send this when it's processed the last frame in the queue and you've asked to be notified with a `REPORT_QUEUE_DRAINED` command. If no media is received within the next 20ms, a silence frame will be sent to the core. This is a one-time notification. You must send additional `REPORT_QUEUE_DRAINED` commands to get more notifications.
149
147
@@ -161,7 +159,7 @@ All configuration is done in the common [websocket_client.conf](/Latest_API/API_
161
159
162
160
## Creating the Channel
163
161
164
-
### Using the Dial() Dialplan App
162
+
### Using the [Dial() Dialplan App](/Latest_API/API_Documentation/Dialplan_Applications/Dial/)
***<connection_id>**: For outgoing connections, this is the name of the pre-defined client connection from websocket_client.conf. For incoming connections, this must be the special `INCOMING` id.
174
172
***<options>**:
175
173
*`c(<codec>)`: If not specified, the first codec from the caller's channel will be used. Having said that, if your app is expecting a specific codec, you should specify it here or you may be getting audio in a format you don't expect.
176
-
*`n`: Don't auto-answer the WebSocket channel upon successful connection. Set this if you wish to answer the channel yourself. You can then send an `ANSWER` TEXT message on the websocket when you're ready to answer the channel.
174
+
*`n`: Don't auto-answer the WebSocket channel upon successful connection. Set this if you wish to answer the channel yourself. You can then send an `ANSWER` TEXT message on the websocket when you're ready to answer the channel or make a `/channels/<channel_id>/answer` REST call.
### Using the ARI `/channels`, `/channels/<id>` or `/channels/create` REST APIs
183
+
### Using the [ARI `/channels`](/Latest_API/API_Documentation/Asterisk_REST_Interface/Channels_REST_API/) REST APIs
186
184
187
185
You can also create a WebSocket channel using the normal channel API calls and setting the `endpoint` parameter to the same dial string syntax described in the previous section.
188
186
@@ -195,9 +193,9 @@ POST http://server:8088/ari/channels/create?endpoint="WebSocket/INCOMING/c(ulaw)
195
193
196
194
The first example will create and dial the channel then connect to your app using the "media_connection1" websocket_client configuration. The channel will auto answer when the websocket connection is established. The second example will create the channel but not dial or auto-answer it. Instead the channel driver will wait for your app to connect to it. You can then dial and answer it yourself when appropriate. You can still omit the `n` to have incoming connections auto-answered.
197
195
198
-
### Using ARI External Media (`/channels/externalMedia`)
196
+
### Using [ARI External Media](/Development/Reference-Information/Asterisk-Framework-and-API-Examples/External-Media-and-ARI) (`/channels/externalMedia`)
199
197
200
-
You can also create a channel using externalMedia with a transport of `websocket` and an encapsulation of `none`.
198
+
You can also create a channel using external media with a transport of `websocket` and an encapsulation of `none`.
0 commit comments