Skip to content

Commit b4362ec

Browse files
committed
WebSocket.md: Tweaks to some names and add links
1 parent 45b8994 commit b4362ec

File tree

1 file changed

+33
-35
lines changed

1 file changed

+33
-35
lines changed

docs/Configuration/Channel-Drivers/WebSocket.md

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Outgoing connections require you to pre-configure a websocket client in the `web
2929
exten = _x.,1,Dial(WebSocket/connection1/c(ulaw))
3030
```
3131

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.
3333

3434
### Incoming Connections
3535

@@ -40,9 +40,9 @@ Incoming connections must be made to the global Asterisk HTTP server using the `
4040
exten = _x.,1,Dial(WebSocket/INCOMING/c(ulaw)n)
4141
```
4242

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.
4444

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.
4646

4747
## Protocol
4848

@@ -54,13 +54,13 @@ Media sent _to_ Asterisk _from_ your app is a bit trickier because chances are t
5454

5555
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...
5656

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.
5858

5959
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.
6060

6161
### Max Message Size and Flow Control
6262

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...
6464

6565
/// warning
6666
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.
7474

7575
/// warning
7676
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.
7779
///
7880

7981
Some of the control TEXT messages you can send the driver have already been mentioned but here's the full list:
8082

8183
#### Commands
8284

83-
/// note
84-
All commands are case-sensitive.
85-
///
86-
8785
/// define
88-
`ANSWER`: Answer the WebSocket channel
86+
`ANSWER`
8987

9088
- This will cause the WebSocket channel to be answered.
9189

92-
`HANGUP`: Hangup the WebSocket channel
90+
`HANGUP`
9391

9492
- This will cause the WebSocket channel to be hung up and the websocket to be closed.
9593

96-
`START_BULK_MEDIA`: Start buffering media
94+
`START_MEDIA_BUFFERING`
9795

9896
- Indicates to the channel driver that the following media should be buffered to create properly sized and timed frames.
9997

100-
`END_BULK_MEDIA <optional_id>`: Stop buffering media
98+
`STOP_MEDIA_BUFFERING <optional_id>`
10199

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.
103101

104-
`PAUSE_MEDIA`: Pause media being sent to the Asterisk core
102+
`FLUSH_MEDIA`
105103

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.
107105

108-
`CONTINUE_MEDIA`: Continue media being sent to the Asterisk core
106+
`PAUSE_MEDIA`
109107

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.
111109

112-
`FLUSH_MEDIA`: Flush the buffer
110+
`CONTINUE_MEDIA`
113111

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.
115113

116-
`GET_STATUS`: Get the current queue status
114+
`GET_STATUS`
117115

118116
- This will cause the channel driver to send back a `STATUS` message (described below).
119117

120-
`REPORT_QUEUE_DRAINED`: Request a notification when the frame queue is empty
118+
`REPORT_QUEUE_DRAINED`
121119

122120
- 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.
123121

@@ -127,23 +125,23 @@ All commands are case-sensitive.
127125

128126
/// define
129127

130-
`MEDIA_XOFF`: Stop sending media
128+
`MEDIA_XOFF`
131129

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.
133131

134-
`MEDIA_XON`: Start sending media again
132+
`MEDIA_XON`
135133

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.
137135

138-
`STATUS`: Response from the `GET_STATUS` command
136+
`STATUS`
139137

140138
- 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`
141139

142-
`BULK_MEDIA_END [ <optional_id> ]`: Indicates that a bulk media transfer has finished.
140+
`MEDIA_BUFFERING_COMPLETED [ <optional_id> ]`
143141

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.
145143

146-
`QUEUE_DRAINED`: Response from `REPORT_QUEUE_DRAINED`
144+
`QUEUE_DRAINED`
147145

148146
- 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.
149147

@@ -161,7 +159,7 @@ All configuration is done in the common [websocket_client.conf](/Latest_API/API_
161159

162160
## Creating the Channel
163161

164-
### Using the Dial() Dialplan App
162+
### Using the [Dial() Dialplan App](/Latest_API/API_Documentation/Dialplan_Applications/Dial/)
165163

166164
The full dial string is as follows:
167165

@@ -173,7 +171,7 @@ Dial(WebSocket/<connection_id>/<options>[,<timeout>[,<dial_options>]])
173171
* **&lt;connection_id&gt;**: 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.
174172
* **&lt;options&gt;**:
175173
* `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.
177175

178176
Examples:
179177

@@ -182,7 +180,7 @@ Dial(WebSocket/connection1/c(alaw)n)
182180
Dial(WebSocket/INCOMING/c(slin16))
183181
```
184182

185-
### 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
186184

187185
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.
188186

@@ -195,9 +193,9 @@ POST http://server:8088/ari/channels/create?endpoint="WebSocket/INCOMING/c(ulaw)
195193

196194
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.
197195

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`)
199197

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`.
201199

202200
Example:
203201

0 commit comments

Comments
 (0)