如何在freeswitch esl java外联模式下使用esl接口时,设置无应答超时时间

freeswitch 用ESL originate实现回拨
在voip电话中,如果主叫不在线的话就要用回拨方式实现voip通话了回拨就要用到originate命令了originate
user/1000 &bridge(user/2000)fs会先呼通1000作为主叫,然后再去呼叫2000实际上回拨与直拨的区别就在于主叫的接通方式,呼被叫的流程是一样的直拨发起呼叫时建立起会话,然后转入dialplan的extension回拨是在主叫接通时建立起会话,然后转入dialplan的extension建立会话之后呼被叫的流程是一样的originate是这样来实现的 originate user/ XML default呼通主叫后,转入dialplan(2000 XML default)
随机推荐程序问答结果
如对文章有任何疑问请提交到,或者您对内容不满意,请您反馈给我们发贴求解。
,机器学习分类整理更新日期:: 00:42:03
如需转载,请注明文章出处和来源网址:
本文WWW.DOC100.NET DOC100.NET版权所有。5316人阅读
FreeSWITCH ESL (Event Socket Library)
Event Socket Library quick starter
Introduction
The Event Socket Library, or ESL, is a library that aims to ease controlling FreeSWITCH from external applications, that can be written in any language and run in any operating system. It's written in C and has bindings for many languages: Perl, Python, PHP,
Lua, Ruby, C# and Java.
The library controls FreeSWITCH through TCP connections, so the application doesn't have to be on the same server where FreeSWITCH is running. An ESL application has access to all the API commands exported by FreeSWITCH, just like it's own native command line
interface (fs_cli) has. fs_cli is actually written using ESL.
Installation
Download the nightly snapshot from http://files.freeswitch.org/freeswitch-snapshot.tar.gz and follow the steps for your operating system:
Install dependencies, as described on http://wiki.freeswitch.org/wiki/Installation_Guide#Common_PrerequisitesDecompress freeswitch-snapshot.tar.gz and enter the newly created directory&Run:&./bootstrap.sh && ./configure && make && sudo make installInstall if desired:&sudo make install
Install Visual Studio 2008 or 2010. Either the express or full versionDecompress freeswitch-snapshot.tar.gzOpen the appropriate solution file for your Visual Studio version. Freeswitch.2008.express.sln for Visual Studio 2008, for example.Build the solutionInstall if desired
Operation modes
Applications can receive and generate calls and, for that to be possible, ESL has two modes of operation:&inbound&and&outbound.
Inbound mode
In this mode, the application originate calls. It can also for example, originate calls, check users' status, load a FreeTDM span, etc.
The application (client) actively connects to the FreeSWITCH (server) in this mode, and runs commands.
Here's an example, written in C, that runs the api command status, print it out and exists:
#include &stdio.h&
#include &stdlib.h&
#include &esl.h&
int main(void)
esl_handle_t handle = {{0}};
esl_connect(&handle, &localhost&, 8021, NULL, &ClueCon&);
esl_send_recv(&handle, &api status\n\n&);
if (handle.last_sr_event && handle.last_sr_event-&body) {
printf(&%s\n&, handle.last_sr_event-&body);
// this is unlikely to happen with api or bgapi (which is hardcoded above) but prefix but may be true for other commands
printf(&%s\n&, handle.last_sr_reply);
esl_disconnect(&handle);
This code was copied from testclient.c, bundled with ESL source code, that comes on the FreeSWITCH tree under libs/esl. To manually compile testclient.c (or your own program), assuming you're on libs/esl directory, run:
gcc -o testclient testclient.c -lpthread -lm -lesl -L. -Isrc/include
user@localhost.localdomain esl $ ./testclient
UP 0 years, 0 days, 3 hours, 6 minutes, 23 seconds, 506 milliseconds, 232 microseconds
0 session(s) since startup
0 session(s) 0/30
1000 session(s) max
min idle cpu 0.00/100.00
Outbound mode
In this mode, the application receive calls.
FreeSWITCH (server) connects to the application (client) whenever it receives a call that's routed to event_socket, with one of the following dialplan actions:
application=&socket& data=&fs_server-hostname:8084&
application=&socket& data=&fs_server-hostname:8084 async&
application=&socket& data=&fs_server-hostname:8084 full&
application=&socket& data=&fs_server-hostname:8084 async full&
Once FreeSWITCH hits one of those actions, it’ll attempt to connect to&fs_server-hostname&on port&8084. The call isn’t automatically answered by the socket application, but instead FreeSWITCH transfers the control
of the call to the application, which can decide to answer the call or not.
There are two optional keywords passed as parameters to these actions. They are:
async: When used, replies to commands are returned promptly. This means that the application might receive a reply before the command has actually finished executing. When the command is finished, the application will receive an event indicating
that. If an application requires the outbound socket to generally behave asynchronously and, just on some particular commands to wait until the command finishes executing (synchronously), the application has to set&event-lock&to true:&event-lock:
full: When not set, the application is limited to control the call in place. When set, it allows the application to fully control FreeSWITCH.
More information on outbound socket can be found on http://wiki.freeswitch.org/wiki/Event_Socket_Outbound
The following example was copied from testserver.c, also bundled with ESL. It answers a call and put the caller into a conference. Comments were added for clarity:
#include &stdio.h&
#include &stdlib.h&
#include &esl.h&
static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
esl_handle_t handle = {{0}};
int done = 0;
esl_status_t status;
time_t exp = 0;
if (fork()) {
close(client_sock);
/* attach our handle to the socket */
esl_attach_handle(&handle, client_sock, addr);
esl_log(ESL_LOG_INFO, &Connected! %d\n&, handle.sock);
/* filter just the events from our channel, ignore the rest */
esl_filter(&handle, &unique-id&, esl_event_get_header(handle.info_event, &caller-unique-id&));
/* subscribe to these events */
esl_events(&handle, ESL_EVENT_TYPE_PLAIN, &SESSION_HEARTBEAT CHANNEL_ANSWER CHANNEL_ORIGINATE CHANNEL_PROGRESS CHANNEL_HANGUP &
&CHANNEL_BRIDGE CHANNEL_UNBRIDGE CHANNEL_OUTGOING CHANNEL_EXECUTE CHANNEL_EXECUTE_COMPLETE DTMF CUSTOM conference::maintenance&);
/* instruct FreeSWITCH to wait for the last channel event before closing the TCP connection */
esl_send_recv(&handle, &linger&);
/* answer the call */
esl_execute(&handle, &answer&, NULL, NULL);
/* put the caller on a conference */
esl_execute(&handle, &conference&, &3000@default&, NULL);
/* poll the socket until the last event is received, or an error occurs */
while((status = esl_recv_timed(&handle, 1000)) != ESL_FAIL) {
if (done) {
if (time(NULL) &= exp) {
} 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 (!strcmp(dispo, &linger&)) {
esl_log(ESL_LOG_INFO, &Waiting 5 seconds for any remaining events.\n&);
exp = time(NULL) + 5;
esl_log(ESL_LOG_INFO, &Disconnected! %d\n&, handle.sock);
esl_disconnect(&handle);
int main(void)
esl_global_set_default_logger(7);
esl_listen(&localhost&, 8084, mycallback);
SIP to TDM gateway example:
#include &stdio.h&
#include &stdlib.h&
#include &esl.h&
static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
esl_handle_t handle = {{0}};
int done = 0;
esl_status_t status;
time_t exp = 0;
char call_url[80];
if (fork()) {
close(client_sock);
/* attach our handle to the socket */
esl_attach_handle(&handle, client_sock, addr);
/* filter just the events from our channel, ignore the rest */
esl_filter(&handle, &unique-id&, esl_event_get_header(handle.info_event, &caller-unique-id&));
/* subscribe to these events */
esl_events(&handle, ESL_EVENT_TYPE_PLAIN, &SESSION_HEARTBEAT CHANNEL_ANSWER CHANNEL_ORIGINATE CHANNEL_PROGRESS CHANNEL_HANGUP &
&CHANNEL_BRIDGE CHANNEL_UNBRIDGE CHANNEL_OUTGOING CHANNEL_EXECUTE CHANNEL_EXECUTE_COMPLETE DTMF CUSTOM conference::maintenance&);
/* instruct FreeSWITCH to wait for the last channel event before closing the TCP connection */
esl_send_recv(&handle, &linger&);
/* get the destination number and create the call url.
here we'll use any channel from the span named &wp1& to dial */
snprintf(call_url, sizeof(call_url), &freetdm/wp1/a/%s&, esl_event_get_header(handle.info_event, &channel-destination-number&));
esl_log(ESL_LOG_INFO, &Bridging call to %s...\n&, call_url);
/* bridge the call to freetdm */
esl_execute(&handle, &bridge&, call_url, NULL);
/* poll the socket until the last event is received, or an error occurs */
while((status = esl_recv_timed(&handle, 1000)) != ESL_FAIL) {
if (done) {
if (time(NULL) &= exp) {
} 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 (!strcmp(dispo, &linger&)) {
esl_log(ESL_LOG_INFO, &Waiting 5 seconds for any remaining events.\n&);
exp = time(NULL) + 5;
esl_log(ESL_LOG_INFO, &Disconnected! %d\n&, handle.sock);
esl_disconnect(&handle);
int main(void)
esl_global_set_default_logger(7);
esl_listen(&localhost&, 8084, mycallback);
If we want to create a TDM to SIP gateway, we just have to change the call_url from the last example. The full program would then become:
#include &stdio.h&
#include &stdlib.h&
#include &esl.h&
static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr)
esl_handle_t handle = {{0}};
int done = 0;
esl_status_t status;
time_t exp = 0;
char call_url[80];
if (fork()) {
close(client_sock);
/* attach our handle to the socket */
esl_attach_handle(&handle, client_sock, addr);
/* filter just the events from our channel, ignore the rest */
esl_filter(&handle, &unique-id&, esl_event_get_header(handle.info_event, &caller-unique-id&));
/* subscribe to these events */
esl_events(&handle, ESL_EVENT_TYPE_PLAIN, &SESSION_HEARTBEAT CHANNEL_ANSWER CHANNEL_ORIGINATE CHANNEL_PROGRESS CHANNEL_HANGUP &
&CHANNEL_BRIDGE CHANNEL_UNBRIDGE CHANNEL_OUTGOING CHANNEL_EXECUTE CHANNEL_EXECUTE_COMPLETE DTMF CUSTOM conference::maintenance&);
/* instruct FreeSWITCH to wait for the last channel event before closing the TCP connection */
esl_send_recv(&handle, &linger&);
/* get the destination number and create the call url.
here we assume we're receiving a call from TDM and we bridge it to a local extension,
registered on the 'internal' sofia profile */
snprintf(call_url, sizeof(call_url), &sofia/internal/%s%192.168.2.19&, esl_event_get_header(handle.info_event, &channel-destination-number&));
esl_log(ESL_LOG_INFO, &Bridging call to %s...\n&, call_url);
/* bridge the call to freetdm */
esl_execute(&handle, &bridge&, call_url, NULL);
/* poll the socket until the last event is received, or an error occurs */
while((status = esl_recv_timed(&handle, 1000)) != ESL_FAIL) {
if (done) {
if (time(NULL) &= exp) {
} 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 (!strcmp(dispo, &linger&)) {
esl_log(ESL_LOG_INFO, &Waiting 5 seconds for any remaining events.\n&);
exp = time(NULL) + 5;
esl_log(ESL_LOG_INFO, &Disconnected! %d\n&, handle.sock);
esl_disconnect(&handle);
int main(void)
esl_global_set_default_logger(7);
esl_listen(&localhost&, 8084, mycallback);
mod_event_socket configuration
In order to configure FreeSWITCH to listen for TCP connections, the user has to configure mod_event_socket and instruct FreeSWITCH to automatically load it. The configuration for mod_event_socket lives on the file conf/autoload_configs/event_socket.conf.xml
and here's a working example:
name=&event_socket.conf& description=&Socket Client&
name=&listen-ip& value=&0.0.0.0&
name=&listen-port& value=&8021&
name=&password& value=&ClueCon&
name=&apply-inbound-acl& value=&lan&
With this configuration, mod_event_socket will listen for TCP connections on port 8021 on all the available network addresses. But, it'll just accept the connections coming from LAN (which is a variable that's defined at conf/vars.xml file). The client has
to authenticate with &ClueCon& as password.
References
FreeSWITCH installation guide:&Windows installation guide:&Mod_event_socket:&ESL, Event Socket Library:&Event Socket Outbound:&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:589356次
积分:7492
积分:7492
排名:第1887名
原创:201篇
转载:57篇
评论:78条
(1)(5)(1)(1)(1)(2)(3)(1)(1)(4)(4)(4)(8)(4)(10)(4)(2)(1)(1)(1)(2)(1)(3)(1)(1)(3)(1)(1)(2)(1)(3)(9)(10)(5)(5)(9)(1)(4)(3)(2)(3)(1)(1)(5)(2)(4)(1)(5)(6)(4)(1)(3)(4)(2)(4)(6)(5)(3)(2)(4)(6)(2)(4)(1)(1)(2)(5)(1)(1)(7)(4)(3)(1)(2)(3)(2)(4)(3)(3)(4)(7)(3)<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&FreeSwitch ESL——Event Object,Connect Object(事件套接字的事件对象及连接对象)
FreeSwitch ESL——Event Object,Connect Object(事件套接字的事件对象及连接对象)
freeSwitch
Event Object
new($event_type [, $event_subclass])
作用:实例化一个新的事件对象,以便于使用以下的方法。
serialize([$format])
作用:将事件转化为冒号分割形如”name:value”的键对。$format的&#20540;可以为:
1.&&&&&&“xml“
2.&&&&&&“json”
3.&&&&&&“plain”(default)
setPriority
setPriority([$number])
作用:设置事件的优先级
getHeader($header_name)
作用:根据一个事件对象中的$header_name来获取头部&#20540;
作用:获得事件对象的正文
作用:获得事件对象的类型
addBody($value)
作用:将$value添加到事件对象的正文中。该对象可能在同一个事件对象中被多次调用
addHeader($header_name, $value)
作用:向事件对象中添加一对&#20540;到头域中。该对象可能在同一个事件对象中被多次调用
delHeader($header_name)
作用:在事件对象中删除名字叫$header_name的头域
firstHeader
firstHeader()
作用:将指针设置为指向事件对象的一个头域,并且返回第一个头域的键&#20540;。该函数必须在nextHeader对象调用前调用
nextHeader
nextHeader()
作用:将指针指向事件对象的下一个头域,并返回它的键&#20540;。调用它之前必须先调用firstHeader来设置指针!若当前位置已经是头域的最后一个节点,则调用该函数后将指向NULL
Connection Object
new($host, $port, $password)
作用:根据一个已存在的套接字句柄初始化一个ESL连接对象实例。
仅在Outbound(FreeSwitch作为客户端)模式下有效。即使在inbound模式下传递一个有效的套接字句柄也是无效的。
作用:初始化一个ESL连接对象实例。后面三个参数分别为主机名、端口号、密码。
该函数仅在inbound模式(FreeSwitch作为服务端)下有效。换而言之,该函数的目的是创建一个连接至FreeSWITCH的对象,并且它并未绑定到任何的呼叫或者信道上。
它并没有初始化通道信息(因为inbound连接并未绑定到任一个信道上)。简单来说,如果调用getInfo()函数永远返回NULL。
socketDescriptor
socketDescriptor()
作用:如果连接对象已连接,则返回该连接对象的UNIX文件描述句柄(FD)。
connected()
作用:测试连接对象是否已连接。已连接则返回1,否则返回0
作用:当FreeSwitch在outbound模式下连接时,它将在初始化阶段首先发送”CHANNEL_DATE”事件。该函数将返回跟该对象相关的信道信息。
当FreeSwitch在inbound模式下,将返回NULL
send($command)
作用:发送一个命令至FreeSwitch
它不会等待一个应答,而需要调用recvEvent或者recvEventTimed来循环等待接受事件。该应答将包含一个叫“content-type”的头域,该头域包含或者“command/reply”的&#20540;。
为了自动等待应答事件,可以使用sendRecv()代替。
sendRecv($command)
作用:sendRecv($command)在调用的时候,会先调用send($command),然后在调用recvEvent(),然后返回一个ESL事件的实例。
recvEvent()会在一个循环中调用并一直阻塞知道收到一个头域包含”api/response”或者“command/reply”的&#20540;,然后再返回ESL事件对象实例。
在此期间收到的所有事件将保存到一个内部队列中,这些事件可以在后续的recvEvent()中取到。
api($command[, $arguments])
作用:向FreeSWITCH服务器发送一个API命令,这个命令将处于阻塞状态直到命令执行结束。
api($command,$args)等效于sendRecv(“api$command $args)
bgapi($command[, $arguments][,$custom_job_uuid])
作用:向FreeSWITCH服务器发送一个后台API命令,该命令将在它自己的线程中执行。
bgapi($command,$args)等效于sendRecv(“bgapi$command $args)。
sendEvent($send_me)
作用:向FreeSwitch发送一个事件。
recvEvent()
作用:向FreeSwitch返回一个接收到的事件。如果接收到事件,该函数在处于阻塞状态,知道新事件来临。
如果在呼叫期间sendRecv()队列中有事件,那么队列中的第一个事件将被返回,并从队列中删除。换句话说,在连接中事件可以被读取。
recvEventTimed
recvEventTimed($milliseconds)
作用:类&#20284;于recvEvent(),但是它会阻塞$milliseconds毫秒.
如果将参数设置为0那么它将会立即返回,这个特性在轮询中特别有用。
filter($header, $value)
作用:用于安装一个过滤器。该过滤器是对输入过滤,而不是对输出过滤。即符合条件的才能进入系统。
events($event_type,$value)
作用:$event_type的&#20540;可以为”plain“或者”xml”,其他任何输入都将被解释为”plain”
如果要调用myevents(event的一个特殊情况,用于outbound模式中)必须使用sendRecv(“myevents”)来调用,千万用events来调用。
execute($app[, $arg][, $uuid])
作用:执行一个拨号计划的应用,并且等到从服务器发送过来的应答。套接字的连接不是固定在一个信道上(大部分情况下为inbound模式),三个参数都是必要的,其中uuid指明了为app指明了信道信息。
该函数将返回一个包含应答的ESL事件对象。通过getHeader(‘Reply-Text”)可以取出应答&#20540;。如果应答&#20540;为”&#43;OK[Success Message]则表示成功,“-ERR [Error Message]表示失败。
可以通过以下的例子看看当调用excuse()命令后如何获取uuid。
在inbound模式下,可以根据以下命令获得一个新的uuid
$uuid = $esl-&api(&create_uuid&)-&getBody();
在outbound模式下,可以根据以下命令获得
$uuid = $esl-&getInfo()-&getHeader(&unique-id&)
executeAsync
executeAsync($app[, $arg][, $uuid])
作用:和execute一样,但是它在等待服务器应答的时候不会阻塞。其实这个函数本质上也是调用了execute()函数,只不过增加了”async:true”的头而已。
setAsyncExecute
setAsyncExecute($value)
作用:强制将套接字连接设置为异步模式。该命令在outbound模式下不起作用。
$value为1表示强制开启异步模式,0为同步模式。
特别要注意的是,调用setAsysncExecute(1)的本质就是调用带“asysnc:true”头的execute()函数。其他套接字路由不受此设置的影响。
setEventLock
setEventLock($value)
作用:强制让套接字连接打开同步模式。这个命令在outbound模式不起作用,因为在dialplan中没有将它设置为异步模式,因为这些连接已经处于同步模式了。
$value为1表示打开同步模式,0表示不强制打开。
要注意的是,调用setEventLock(1)的操作等价于调用带”event-lock:true”头的execute()函数。其他的事件套接字路由不受此设置的影响。
disconnect
disconnect()
作用:关闭连接
freeSwitch1.4版本(后的master版本)的C语言调用示例如下
int main(void)
char *private_data = &some private string or struct ...&;
esl_global_set_default_logger(7);
esl_listen_threaded(&localhost&, 8040, mycallback, private_data, 100000);
Event Socket Command翻译出处:http://wiki.freeswitch.org/wiki/Event_Socket
其他翻译出处:https://freeswitch.org/confluence/display/FREESWITCH/Event&#43;Socket&#43;Library
我的热门文章
即使是一小步也想与你分享}

我要回帖

更多关于 freeswitch esl php 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信