【FreeSwitch开发实践】在NodeJS中用ESL连接FreeSwitch

系列文章目录

【FreeSwitch开发实践】centos7下编译安装freeswitch及常见编译问题的解决
【FreeSwitch开发实践】freeswitch配置wss
【FreeSwitch开发实践】freeswitch配置wss证书问题 Encrypted Alert/Certification Unknown
【FreeSwitch开发实践】ESL简介
【FreeSwitch开发实践】ESL配置



前言

前文对ESL作了简介和配置的说明,本文将介绍在NodeJS中使用ESL,通过一些简单的例子,对如何在NodeJS使用ESL作了一个说明。
在NodeJS中ESL的实现,是modesl模块,这个模块需要下载安装。


一、modesl安装

modesl是NodeJS下ESL的实现模块,下载命令:

npm install modesl

效果

在这里插入图片描述

二、NodeJS中引用modesl

const esl=require('F:/02_test/NodeJsDemo/ESL-test/node_modules/modesl');

代码解释:

F:/02_test/NodeJsDemo/ESL-test/node_modules/modeslmodesl的安装目录, 作者安装到了项目的当前目录,读者实验的时候需要改成自己安装modesl的目录。


三、modesl连接FreeSwitch

const http=require('http');
const server=http.createServer();

const esl=require('D:/projects/Tests/ESL-NodeJS/node_modules/modesl');
//console.log(esl);

const conn=new esl.Connection('152.136.12.39', 8021, 'ClueCon',function(){
			
    conn.api('version',function(response){
        console.log(response.getBody());
    });
   
});

server.on('request',function(request,response){
	const url=request.url;	
	if(url === '/'){
		
        conn.bgapi('originate user/1000 &echo',function(response){
				//console.log(response);
			})
	
	}else if(url === '/index'){
		response.end('/index');
	}else{
		response.end("<h1 style='color:red;'>404 Not Found</h1>");
	}
})
server.listen(3001,function(){
	console.info('server is running...');
})

代码解释:

1 const conn=new esl.Connection('152.136.12.38', 8021, 'ClueCon' 是ESL连接,参数分别是FreeSwitch服务器的IP端口密码,具体配置见FreeSwitch的配置文件event_socket.conf.xml(可参考《【FreeSwitch开发实践】ESL配置》)。
2 conn.api('version' 执行api version 命令, 此命令是FreeSwitch的versionapi, 用途是获取FreeSwitch的版本(在《【FreeSwitch开发实践】ESL简介》有介绍)。

运行:

执行ESL连接的方法是:
打开浏览器,在地址栏输入: localhost:3001 , 回车

输出:
在这里插入图片描述
目录结构:
在这里插入图片描述

四、ESL事件订阅

ESL除了可以直接”执行"FreeSwitch的内部api或app,还可以通过事件订阅,获取几乎所有FreeSwitch的事件,两者结合,ESL可以达到像在FreeSwitch命令行上运行内部api或app几样的效果。
下面通originate命令拨打软电话,订阅answer(接听)事件和hangup(挂断)事件,来演示ESL订阅事件流程。

const http=require('http');
const server=http.createServer();

const esl=require('D:/projects/Tests/ESL-NodeJS/node_modules/modesl');
//console.log(esl);

const conn=new esl.Connection('152.136.12.39', 8021, 'ClueCon',function(){
			
    conn.api('version',function(response){
        console.log(response.getBody());
    });

    conn.subscribe([
        'CHANNEL_ANSWER',
        'CHANNEL_HANGUP',
        'CHANNEL_HANGUP_COMPLETE',
        'CUSTOM my_event'
    ], function(evt) {
        console.log(evt)    
    });

    conn.on('esl::event::CUSTOM::**', function(evt) {
        console.log(evt);
    });

    conn.on('esl::event::CHANNEL_ANSWER::*', function(evt) {
        console.log(evt);
    });

    conn.on('esl::event::CHANNEL_HANGUP::*', function(evt) {
        console.log(evt);
    });

    conn.on('esl::event::CHANNEL_HANGUP_COMPLETE::*', function(evt) {
        console.log(evt);
    });
   
});

server.on('request',function(request,response){
	const url=request.url;	
	if(url === '/'){
		
        conn.bgapi('originate user/1000 &echo',function(response){
				//console.log(response);
			})
	
	}else if(url === '/index'){
		response.end('/index');
	}else{
		response.end("<h1 style='color:red;'>404 Not Found</h1>");
	}
})
server.listen(3001,function(){
	console.info('server is running...');
})

代码解释:

1 conn.bgapiapi命令的异步版本, 都用于执行FreeSwitch的api或app
2 originate user/1000 &echo 是给软电话用户1000通话, echo 是FreeSwitch自带的回音app,接通之后你和说什么,它就原样回过来
3 conn.subscribe 事件订阅 是本节的重点, 参数是事件名称,其中CUSTOM my_event 订阅自定义事件, 名称为my_event
4 CHANNEL_ANSWER 用户接听电话事件
5 CHANNEL_HANGUP_COMPLETE 挂断事件
6 conn.on('esl::event::CHANNEL_ANSWER::*' 对事件CHANNEL_ANSWER监听
7 conn.on('esl::event::CHANNEL_HANGUP_COMPLETE::*' 对事CHANNEL_HANGUP_COMPLETE监听
8 conn.on('esl::event::CUSTOM::**',对自定义事件监听

输出结果:
answer部分:

{
  headers: [
    { name: 'Event-Name', value: 'CHANNEL_ANSWER' },
    {
      name: 'Core-UUID',
      value: 'e2232c8b-7e79-4404-8a91-54e0f94b96ca'
    },
    { name: 'FreeSWITCH-Hostname', value: 'VM-8-10-centos' },
    { name: 'FreeSWITCH-Switchname', value: 'VM-8-10-centos' },
    { name: 'FreeSWITCH-IPv4', value: '10.0.8.1' },
    { name: 'FreeSWITCH-IPv6', value: 'fe80::5054:ff:fe58:28ea' },
    { name: 'Event-Date-Local', value: '2022-07-10 17:07:27' },
    { name: 'Event-Date-GMT', value: 'Sun, 10 Jul 2022 09:07:27 GMT' },
    { name: 'Event-Date-Timestamp', value: '1657444047428307' },
    { name: 'Event-Calling-File', value: 'switch_channel.c' },
    {
      name: 'Event-Calling-Function',
      value: 'switch_channel_perform_mark_answered'
    },
    { name: 'Event-Calling-Line-Number', value: '3884' },
    { name: 'Event-Sequence', value: '343988' },
    { name: 'Channel-State', value: 'CS_CONSUME_MEDIA' },
    { name: 'Channel-Call-State', value: 'RINGING' },
    { name: 'Channel-State-Number', value: '7' },
    {
      name: 'Channel-Name',
      value: 'sofia/internal/1000@61.149.73.243:4446'
    },
    {
      name: 'Unique-ID',
      value: '91eafbfe-e998-4b30-bfaa-8e06c93915a3'
    },
    { name: 'Call-Direction', value: 'outbound' },
    { name: 'Presence-Call-Direction', value: 'outbound' },
    { name: 'Channel-HIT-Dialplan', value: 'false' },
    { name: 'Channel-Presence-ID', value: '1000@10.0.8.1' },
    {
      name: 'Channel-Call-UUID',
      value: '91eafbfe-e998-4b30-bfaa-8e06c93915a3'
    },
    { name: 'Answer-State', value: 'answered' },
    { name: 'Channel-Read-Codec-Name', value: 'PCMU' },
    { name: 'Channel-Read-Codec-Rate', value: '8000' },
    { name: 'Channel-Read-Codec-Bit-Rate', value: '64000' },
    { name: 'Channel-Write-Codec-Name', value: 'PCMU' },
    { name: 'Channel-Write-Codec-Rate', value: '8000' },
    { name: 'Channel-Write-Codec-Bit-Rate', value: '64000' },
    { name: 'Caller-Direction', value: 'outbound' },
    { name: 'Caller-Logical-Direction', value: 'outbound' },
    { name: 'Caller-Caller-ID-Number', value: '0000000000' },
    { name: 'Caller-Orig-Caller-ID-Number', value: '0000000000' },
    { name: 'Caller-Callee-ID-Name', value: 'Outbound Call' },
    { name: 'Caller-Callee-ID-Number', value: '1000' },
    { name: 'Caller-Network-Addr', value: '61.149.73.243' },
    { name: 'Caller-ANI', value: '0000000000' },
    { name: 'Caller-Destination-Number', value: '1000' },
    {
      name: 'Caller-Unique-ID',
      value: '91eafbfe-e998-4b30-bfaa-8e06c93915a3'
    },
    { name: 'Caller-Source', value: 'src/switch_ivr_originate.c' },
    { name: 'Caller-Context', value: 'default' },
    {
      name: 'Caller-Channel-Name',
      value: 'sofia/internal/1000@61.149.73.243:4446'
    },
    { name: 'Caller-Profile-Index', value: '1' },
    { name: 'Caller-Profile-Created-Time', value: '1657444039428319' },
    { name: 'Caller-Channel-Created-Time', value: '1657444039428319' },
    { name: 'Caller-Channel-Answered-Time', value: '1657444047428307' },
    { name: 'Caller-Channel-Progress-Time', value: '1657444039508312' },
    { name: 'Caller-Channel-Progress-Media-Time', value: '0' },
    { name: 'Caller-Channel-Hangup-Time', value: '0' },
    { name: 'Caller-Channel-Transfer-Time', value: '0' },
    { name: 'Caller-Channel-Resurrect-Time', value: '0' },
    { name: 'Caller-Channel-Bridged-Time', value: '0' },
    { name: 'Caller-Channel-Last-Hold', value: '0' },
    { name: 'Caller-Channel-Hold-Accum', value: '0' },
    { name: 'Caller-Screen-Bit', value: 'true' },
    { name: 'Caller-Privacy-Hide-Name', value: 'false' },
    { name: 'Caller-Privacy-Hide-Number', value: 'false' },
    { name: 'variable_direction', value: 'outbound' },
    { name: 'variable_is_outbound', value: 'true' },
    {
      name: 'variable_uuid',
      value: '91eafbfe-e998-4b30-bfaa-8e06c93915a3'
    },
    {
      name: 'variable_call_uuid',
      value: '91eafbfe-e998-4b30-bfaa-8e06c93915a3'
    },
    { name: 'variable_session_id', value: '8893' },
    { name: 'variable_sip_profile_name', value: 'internal' },
    { name: 'variable_text_media_flow', value: 'disabled' },
    {
      name: 'variable_channel_name',
      value: 'sofia/internal/1000@61.149.73.243:4446'
    },
    {
      name: 'variable_sip_destination_url',
      value: 'sip:1000@61.149.73.243:4446'
    },
    { name: 'variable_dialed_user', value: '1000' },
    { name: 'variable_dialed_domain', value: '10.0.8.1' },
    { name: 'variable_sip_invite_domain', value: '10.0.8.1' },
    { name: 'variable_presence_id', value: '1000@10.0.8.1' },
    { name: 'variable_originate_early_media', value: 'true' },
    { name: 'variable_audio_media_flow', value: 'sendrecv' },
    { name: 'variable_local_video_ip', value: '10.0.8.1' },
    { name: 'variable_local_video_port', value: '20014' },
    { name: 'variable_video_media_flow', value: 'sendrecv' },
    {
      name: 'variable_rtp_local_sdp_str',
      value: 'v=0\r\n' +
        'o=FreeSWITCH 1657424125 1657424126 IN IP4 10.0.8.1\r\n' +
        's=FreeSWITCH\r\n' +
        'c=IN IP4 10.0.8.1\r\n' +
        't=0 0\r\n' +
        'm=audio 19914 RTP/AVP 9 0 8 101\r\n' +
        'a=rtpmap:9 G722/8000\r\n' +
        'a=rtpmap:0 PCMU/8000\r\n' +
        'a=rtpmap:8 PCMA/8000\r\n' +
        'a=rtpmap:101 telephone-event/8000\r\n' +
        'a=fmtp:101 0-15\r\n' +
        'a=ptime:20\r\n' +
        'a=sendrecv\r\n' +
        'm=video 20014 RTP/AVP 102\r\n' +
        'b=AS:3072\r\n' +
        'a=rtpmap:102 VP8/90000\r\n' +
        'a=sendrecv\r\n' +
        'a=rtcp-fb:102 ccm fir\r\n' +
        'a=rtcp-fb:102 ccm tmmbr\r\n' +
        'a=rtcp-fb:102 nack\r\n' +
        'a=rtcp-fb:102 nack pli\r\n'
    },
    {
      name: 'variable_sip_outgoing_contact_uri',
      value: '<sip:mod_sofia@152.136.12.39:5060>'
    },
    { name: 'variable_sip_req_uri', value: '1000@61.149.73.243:4446' },
    { name: 'variable_sofia_profile_name', value: 'internal' },
    { name: 'variable_recovery_profile_name', value: 'internal' },
    {
      name: 'variable_sofia_profile_url',
      value: 'sip:mod_sofia@152.136.12.39:5060'
    },
    {
      name: 'variable_sip_local_network_addr',
      value: '152.136.12.39'
    },
    { name: 'variable_sip_reply_host', value: '61.149.73.243' },
    { name: 'variable_sip_reply_port', value: '4446' },
    { name: 'variable_sip_network_ip', value: '61.149.73.243' },
    { name: 'variable_sip_network_port', value: '4446' },
    { name: 'variable_sip_user_agent', value: 'YATE/4.2.0' },
    {
      name: 'variable_sip_allow',
      value: 'ACK, INVITE, BYE, CANCEL, OPTIONS, INFO'
    },
    {
      name: 'variable_sip_recover_contact',
      value: '<sip:1000@61.149.73.243:4446>'
    },
    {
      name: 'variable_sip_full_via',
      value: 'SIP/2.0/UDP 10.0.8.1;branch=z9hG4bKyK8tvgppgrgae;received=10.0.8.1;rport=5060'
    },
    {
      name: 'variable_sip_recover_via',
      value: 'SIP/2.0/UDP 10.0.8.1;branch=z9hG4bKyK8tvgppgrgae;received=10.0.8.1;rport=5060'
    },
    {
      name: 'variable_sip_full_from',
      value: '<sip:0000000000@10.0.8.1>;tag=6eDFUy11rrNaB'
    },
    {
      name: 'variable_sip_full_to',
      value: '<sip:1000@61.149.73.243:4446>;tag=102329003'
    },
    { name: 'variable_sip_from_user', value: '0000000000' },
    { name: 'variable_sip_from_uri', value: '0000000000@10.0.8.1' },
    { name: 'variable_sip_from_host', value: '10.0.8.1' },
    { name: 'variable_sip_to_user', value: '1000' },
    { name: 'variable_sip_to_port', value: '4446' },
    { name: 'variable_sip_to_uri', value: '1000@61.149.73.243:4446' },
    ... 38 more items
  ],
  hPtr: null,
  type: 'CHANNEL_ANSWER',
  subclass: undefined,
  body: ''
}

*hangup部分:

{
  headers: [
    { name: 'Event-Name', value: 'CHANNEL_HANGUP_COMPLETE' },
    {
      name: 'Core-UUID',
      value: 'e2232c8b-7e79-4404-8a91-54e0f94b96ca'
    },
    { name: 'FreeSWITCH-Hostname', value: 'VM-8-10-centos' },
    { name: 'FreeSWITCH-Switchname', value: 'VM-8-10-centos' },
    { name: 'FreeSWITCH-IPv4', value: '10.0.8.1' },
    { name: 'FreeSWITCH-IPv6', value: 'fe80::5054:ff:fe58:28ea' },
    { name: 'Event-Date-Local', value: '2022-07-10 17:09:22' },
    { name: 'Event-Date-GMT', value: 'Sun, 10 Jul 2022 09:09:22 GMT' },
    { name: 'Event-Date-Timestamp', value: '1657444162368312' },
    {
      name: 'Event-Calling-File',
      value: 'switch_core_state_machine.c'
    },
    {
      name: 'Event-Calling-Function',
      value: 'switch_core_session_reporting_state'
    },
    { name: 'Event-Calling-Line-Number', value: '943' },
    { name: 'Event-Sequence', value: '344222' },
    { name: 'Hangup-Cause', value: 'WRONG_CALL_STATE' },
    { name: 'Channel-State', value: 'CS_REPORTING' },
    { name: 'Channel-Call-State', value: 'HANGUP' },
    { name: 'Channel-State-Number', value: '11' },
    {
      name: 'Channel-Name',
      value: 'sofia/internal/7770015213612938@10.0.8.1'
    },
    {
      name: 'Unique-ID',
      value: '16adc43d-cd80-4dd2-aa6c-234256984688'
    },
    { name: 'Call-Direction', value: 'inbound' },
    { name: 'Presence-Call-Direction', value: 'inbound' },
    { name: 'Channel-HIT-Dialplan', value: 'true' },
    {
      name: 'Channel-Call-UUID',
      value: '16adc43d-cd80-4dd2-aa6c-234256984688'
    },
    { name: 'Answer-State', value: 'hangup' },
    { name: 'variable_direction', value: 'inbound' },
    {
      name: 'variable_uuid',
      value: '16adc43d-cd80-4dd2-aa6c-234256984688'
    },
    {
      name: 'variable_call_uuid',
      value: '16adc43d-cd80-4dd2-aa6c-234256984688'
    },
    { name: 'variable_session_id', value: '8895' },
    { name: 'variable_sip_from_user', value: '7770015213612938' },
    {
      name: 'variable_sip_from_uri',
      value: '7770015213612938@10.0.8.1'
    },
    { name: 'variable_sip_from_host', value: '10.0.8.1' },
    { name: 'variable_video_media_flow', value: 'disabled' },
    { name: 'variable_audio_media_flow', value: 'disabled' },
    { name: 'variable_text_media_flow', value: 'disabled' },
    {
      name: 'variable_channel_name',
      value: 'sofia/internal/7770015213612938@10.0.8.1'
    },
    {
      name: 'variable_sip_call_id',
      value: '2025548018-1584820887-1068544171'
    },
    {
      name: 'variable_ep_codec_string',
      value: 'CORE_PCM_MODULE.pcmu@8000h@20i@64000b,CORE_PCM_MODULE.PCMA@8000h@20i@64000b'
    },
    { name: 'variable_hangup_cause', value: 'WRONG_CALL_STATE' },
    { name: 'variable_hangup_cause_q850', value: '101' }
  ],
  hPtr: null,
  type: 'CHANNEL_HANGUP_COMPLETE',
  subclass: undefined,
  body: ''
}


总结

好了, 以上就是今天的内容, 本文主要对NodeJS中如何安装modesl、连接FreeSwitch、执行FreeSwitch的api或app、及事件订阅作了介绍。如果觉得不错,可以给博主点个关注,你们的支持,是我持续写作的动力。

  • 28
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 59
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 59
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一马途追

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值