当前位置: 首页 > 工具软件 > ESL > 使用案例 >

freeswitch之esl开发

海保臣
2023-12-01

Socket Library,通过它可以与freeswitch进行交互,执行app和api以及接收事件,esl 支持多种语言java、c\c++、golang,php等等。

esl开发支持inbound和outbound模式。

outbound模式,是FS在单个channel中创建并连接到外部tcp server服务,随着会话的结束而断开socket连接。适合控制单个会话的呼叫和语音控制;而Inbound的连接由客户端主动向FS发起连接,更适合接收所有的事件,进行自动呼叫服务。

开发注意事项:

1、outbound模式中为了避免接收不到挂机信号,可以设置linger超时时间来延时FS挂断socket连接。

2、接收事件采用队列模型把原始事件对象先入列,然后开线程处理线程中的事件对象,以避免丢掉事件。

outbound例子:

#include <stdio.h>
#include <stdlib.h>
#include <esl.h>
 
typedef struct{
    esl_handle_t *handle;
    int running;
}esl_callback_t;
 
static void *event_thread(esl_thread_t *me, void *obj)

    int done = 0;
    time_t exp = 0;
    esl_status_t status;
    esl_callback_t *callback = (esl_callback_t *)obj;
    esl_handle_t *handle = callback->handle;
    
    while((status = esl_recv_timed(handle, 1000)) != ESL_FAIL) {
        if (done) {
            if (time(NULL) >= exp) {
                esl_log(ESL_LOG_INFO, "10 seconds timeout.\n");
                callback->running = 0;
                break;
            }
        } else if (status == ESL_SUCCESS) {
            const char *type = esl_event_get_header(handle->last_event, "content-type");
            if (type && !strcasecmp(type, "text/disconnect-notice")) {
                const char *dispo = esl_event_get_header(handle->last_event, "content-disposition");
                esl_log(ESL_LOG_INFO, "Got a disconnection notice dispostion: [%s]\n", dispo ? dispo : "");
                if (dispo && !strcmp(dispo, "linger")) {
                    done = 1;
                    esl_log(ESL_LOG_INFO, "Waiting 10 seconds for any remaining events.\n");
                    exp = time(NULL) + 10;
                }
            }
        }
    }
}
 
 
static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr, void *user_data)
{
    esl_handle_t handle = {{0}};
    esl_callback_t callback = {0};
    
 
    esl_attach_handle(&handle, client_sock, addr);
    handle.event_lock = 1;
 
    esl_log(ESL_LOG_INFO, "Connected! %d\n", handle.sock);
 
    esl_filter(&handle, "unique-id", esl_event_get_header(handle.info_event, "caller-unique-id"));
    esl_events(&handle, ESL_EVENT_TYPE_PLAIN, "CHANNEL_ANSWER CHANNEL_HANGUP CHANNEL_HANGUP_COMPLETE DTMF");
 
    esl_send_recv(&handle, "linger");
    
    callback.handle = &handle;
    callback.running = 1;
    
    esl_thread_create_detached(event_thread, &callback);
 
    esl_execute(&handle, "answer", NULL, NULL);
    esl_execute(&handle, "playback", "/home/test.wav", NULL);
    esl_execute(&handle, "sleep", "1000", NULL);
    esl_execute(&handle, "hangup", NULL, NULL);
    
    while(handle.connected && callback.running){
        usleep(10000);
    }
    
    esl_log(ESL_LOG_INFO, "Disconnected! %d\n", handle.sock);
    esl_disconnect(&handle);
}
 
int main(void)
{
    esl_global_set_default_logger(7);
    esl_listen_threaded("localhost", 8040, mycallback, NULL, 100000);
    
    return 0;
}
inbound例子:
 

 类似资料: