ARI Outbound Websockets

Asterisk can now establish websocket sessions _to_ your ARI applications
as well as accepting websocket sessions _from_ them.
Full details: http://s.asterisk.net/ari-outbound-ws

Code change summary:
* Added an ast_vector_string_join() function,
* Added ApplicationRegistered and ApplicationUnregistered ARI events.
* Converted res/ari/config.c to use sorcery to process ari.conf.
* Added the "outbound-websocket" ARI config object.
* Refactored res/ari/ari_websockets.c to handle outbound websockets.
* Refactored res/ari/cli.c for the sorcery changeover.
* Updated res/res_stasis.c for the sorcery changeover.
* Updated apps/app_stasis.c to allow initiating per-call outbound websockets.
* Added CLI commands to manage ARI websockets.
* Added the new "outbound-websocket" object to ari.conf.sample.
* Moved the ARI XML documentation out of res_ari.c into res/ari/ari_doc.xml

UserNote: Asterisk can now establish websocket sessions _to_ your ARI applications
as well as accepting websocket sessions _from_ them.
Full details: http://s.asterisk.net/ari-outbound-ws
This commit is contained in:
George Joseph
2025-03-28 06:54:21 -06:00
parent 397cae0208
commit 686f083054
15 changed files with 2948 additions and 963 deletions

View File

@@ -244,4 +244,51 @@ void ast_ari_response_created(struct ast_ari_response *response,
*/
void ast_ari_response_alloc_failed(struct ast_ari_response *response);
/*!
* \brief Create a per-call outbound websocket connection.
*
* \param app_name The app name.
* \param channel The channel to create the websocket for.
*
* This function should really only be called by app_stasis.
*
* A "per_call" websocket configuration must already exist in
* ari.conf that has 'app_name' in its 'apps' parameter.
*
* The channel uniqueid is used to create a unique app_id
* composed of "<app_name>-<channel_uniqueid>" which will be
* returned from this call. This ID will be used to register
* an ephemeral Stasis application and should be used as the
* app_name for the call to stasis_app_exec(). When
* stasis_app_exec() returns, ast_ari_close_per_call_websocket()
* must be called with the app_id to close the websocket.
*
* The channel unique id is also used to detect when the
* StasisEnd event is sent for the channel. It's how
* ast_ari_close_per_call_websocket() knows that all
* messages for the channel have been sent and it's safe
* to close the websocket.
*
* \retval The ephemeral application id or NULL if one could
* not be created. This pointer will be freed by
* ast_ari_close_per_call_websocket(). Do not free
* it yourself.
*/
char *ast_ari_create_per_call_websocket(const char *app_name,
struct ast_channel *channel);
/*!
* \brief Close a per-call outbound websocket connection.
*
* \param app_id The ephemeral application id returned by
* ast_ari_create_per_call_websocket().
*
* This function should really only be called by app_stasis.
*
* \note This call will block until all messages for the
* channel have been sent or 5 seconds has elapsed.
* After that, the websocket will be closed.
*/
void ast_ari_close_per_call_websocket(char *app_id);
#endif /* _ASTERISK_ARI_H */

View File

@@ -84,6 +84,17 @@ int ast_vector_string_split(struct ast_vector_string *dest,
const char *input, const char *delim, int flags,
int (*excludes_cmp)(const char *s1, const char *s2));
/*!
* \brief Join the elements of a string vector into a single string.
*
* \param vec Pointer to the vector.
* \param delim String to separate elements with.
*
* \retval Resulting string. Must be freed with ast_free.
*
*/
char *ast_vector_string_join(struct ast_vector_string *vec, const char *delim);
/*!
* \brief Define a vector structure with a read/write lock
*