日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

freeswitch模块之event_socket

發布時間:2025/6/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 freeswitch模块之event_socket 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是我之前整理的關于freeswitch mod_event_socket的相關內容,這里記錄下,也方便我以后查閱。

mod_event_socket以socket的形式,對外提供控制FS一種途徑, 缺省的IP是127.0.0.1,TCP端口是8021,可以在外部通過sokcet執行API/APP命令。

連接模式

連接分兩種模式: inbound/outbound
mod_event_socket 的默認加載模式是inbound,outbound模式需要在dialplan的配置文件中設置。

InBound模式由于是可以主動連接并可長期穩定保持,且此通道有且只有一個,心跳、外呼和注冊等動作必須通過此種連接完成;

OutBound模式由于是在外線呼入和內線呼出的時候才會觸發socket連接事件,所以是不穩定的,且由于同一時間呼入數量不唯一,所以此連接的數目也是動態變化的,但是由于其每個來電建立一個socket連接,所以在大負荷情況下不會造成命令和事件的堵塞。

使用inbound模式

1、修改acl配置:

配置autoload_configs/acl.conf.xml文件:

<list name="domains" default="deny"><!-- domain= is special it scans the domain from the directory to build the ACL --><node type="allow" domain="$${domain}"/><!-- use cidr= if you wish to allow ip ranges to this domains acl. --><!-- <node type="allow" cidr="192.168.0.0/24"/> --><node type="allow" cidr="192.168.168.0/24"/><node type="allow" cidr="127.0.0.0/24"/> </list>

2、修改esl配置:

配置autoload_configs/event_socket.conf.xml文件:

<configuration name="event_socket.conf" description="Socket Client"><settings><param name="nat-map" value="false"/><param name="listen-ip" value="0.0.0.0"/><param name="listen-port" value="8021"/><param name="password" value="ClueCon"/><param name="apply-inbound-acl" value="domains"/><!--<param name="apply-inbound-acl" value="loopback.auto"/>--><!--<param name="stop-on-bind-error" value="true"/>--></settings> </configuration>

3、重啟freeswitch

4、通過inbound方式使用freeswitch python示例代碼如下:

import socket import json sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 8021)) # send auth sock.send('auth ClueCon\r\n\r\n') # send command sock.send('event json ALL\r\n\r\n') #sock.send('event plain ALL\r\n\r\n') while True:print sock.recv(10240)

使用outbound模式

1、編輯conf/dialplan/default.xml,增加如下內容:

<extension name="123456789 Entrance"><condition field="destination_number" expression="^123456789$"> <action application="socket" data="127.0.0.1:9000 async full" /> <action application="playback" data="$${hold_music}"/><action application="hangup" data="" /> </condition> </extension>

2、啟動監聽服務器 監聽listen-ip:listen-port(如在Linux下可以通過 nc -v -l 9000),

然后撥打配置的電話號碼(本例中為123456789) 即可收到Connection from 127.0.0.1 port 9000 [tcp/*] accepted 的消息, 鍵入connect\n\n即可進入OutBound模式

?

通過socket控制freeswitch

?

可以通過任何支持socket的語言控制freeswitch,這里以python為例子描述怎么通過socket控制freeswitch。

?

  • auth
    語法:

    auth <password>

    當用戶第一次通過mod_event_socket連接到freeswitch時,必須進行認證,認證示例:

    sock.send(“auth ClueCon\r\n\r\n”)
  • api
    執行freeswitch的API命令,阻塞執行。
    語法:
    api?
    示例:

    sock.send('api originate user/1000 &echo\r\n\r\n') sock.send('api originate user/1001 &echo\r\n\r\n')

    socket會將上述兩條指令同時發送給freeswitch,但freeswitch按順序阻塞執行。

  • bgapi
    功能和api相同,非阻塞執行。
    語法:
    bgapi?
    示例:

    sock.send('bgapi originate user/1000 &echo\r\n\r\n') sock.send('bgapi originate user/1001 &echo\r\n\r\n')

    socket會將上述兩條指令同時發送給freeswitch,同時執行。

  • event
    啟動或停止事件流。
    語法:
    event

    format : plain、json、xml
    Event types : 參考freeswitch事件類型
    示例:

    sock.send('event json ALL\r\n\r\n')

    接收freeswitch所有事件,并以json格式返回。

  • noevents
    關閉上一個event開啟的事件
    語法 :
    noevents

    示例:

    sock.send('noevents\r\n\r\n')
  • divert_events
    腳本注冊接收事件的函數分轉到event socket上。
    語法:
    divert_events

  • filter
    設置event socket接收事件的類型。
    語法:
    filter

    示例:
    只訂閱CHANNEL_EXECUTE事件

    sock.send('filter Event-Name CHANNEL_EXECUTE\r\n\r\n')

    只訂閱uuid為34602e08-557a-494a-af47-99e9d55e26ed的事件

    sock.send('filter Unique-ID 34602e08-557a-494a-af47-99e9d55e26ed\r\n\r\n')
  • filter delete
    取消訂閱的事件。
    語法:
    filter delete

    示例:

    sock.send('filter delete Event-Name CHANNEL_EXECUTE\r\n\r\n') sock.send('filter delete Unique-ID 34602e08-557a-494a-af47-99e9d55e26ed\r\n\r\n')
  • nixevents
    設置event socket禁止接收的事件類型。
    語法:

    nixevents <event types | ALL| CUSTOM custom event sub-class>

    示例:
    不訂閱HEARTBEAT事件

    sock.send('nixevent HEARTBEAT\r\n\r\n')
  • sendevent
    發送一個事件到系統隊列中。
    語法:

    sendevent <event-name>

    示例(消息內容):

    sendevent SOME_NAME Event-Name: CUSTOM Event-Subclass: albs::Section-Alarm Section: 33 Alarm-Type: PIR State: ACTIVE
  • sendmsg

    給一個uuid發送一個消息,可以執行其他模塊的應用接口,也可以掛斷電話等。
    語法:

    sendmsg <uuid>

    示例(消息內容):

    sendmsg <uuid> call-command: execute execute-app-name: playback execute-app-arg: /tmp/test.wav
  • execute
    執行一個撥號規則的應用。
    語法:

    sendmsg <uuid> call-command: execute execute-app-name: <one of the applications> execute-app-arg: <application data> loops: <number of times to invoke the command, default: 1>
  • hangup 對活動的呼叫掛機。
    語法:

    sendmsg <uuid> call-command: hangup hangup-cause: <one of the causes listed below>
  • nomedia

    控制freeswitch是否處于實時的媒體路徑,這個命令支持用戶對指定的通道啟用或關閉媒體處理。

    語法:

    sendmsg <uuid> call-command: nomedia nomedia-uuid: <noinfo>
  • log 語法:

    log <level>

    設置日志級別。

  • nolog

    禁止日志。

  • linger

    告訴freeswitch當一個通道掛機時不要關閉socket連接,直到收取相關通道的最后一個事件。

  • nolinger

    關閉上次開啟的linger命令。

?

通過freeswitch提供的ESL庫進行控制?

這里以python為例描述下ESL庫的基本使用及api接口。

安裝ESL

以python為例進行安裝:

cd libs/esl/ make pymod make pymod-install

ESL示例

  • InBound模式

    Python示例代碼:

    import ESL import timehostIp,port,user = "127.0.0.1","8021","ClueCon"con = ESL.ESLconnection(hostIp,port,user) con.events("json","all") for i in range(100):eventData = con.recvEvent()print eventData.getHeader("Event-Name") con.disconnect()
  • OutBound模式

    配置dialplan:

    <action application="socket" data="127.0.0.1:9000 async full"/>

    Python示例代碼:

    import SocketServer import ESLclass ESLRequestHandler(SocketServer.BaseRequestHandler ):def setup(self):print self.client_address, 'connected!'fd = self.request.fileno()con = ESL.ESLconnection(fd)if con.connected():info = con.getInfo()uuid = info.getHeader("unique-id")print uuidcon.execute("answer","", uuid)con.execute("playback","/tmp/sample.wav", uuid)server = SocketServer.ThreadingTCPServer(('', 9000), ESLRequestHandler) server.serve_forever()

ESL接口介紹

eslSetLogLevel函數

該函數用于設置服務器的日志級別,使用方式如下:

eslSetLogLevel(loglevel)

其中loglevel是一個整數變量,從0到7,含義如下:

0 是 EMERG
1 是 ALERT
2 是 CRIT
3 是 ERROR
4 是 WARNING
5 是 NOTICE
6 是 INFO
7 是 DEBUG

ESLconnection對象

ESLconnection對象維護與freeswitch之間的連接,以發送命令并進行事件處理。 成員函數列表如下:

  • socketDescriptor()
    該函數返回連接的UNIX文件句柄

  • connected()
    判斷是否已連接,連接返回1,否則返回0

  • getInfo()

    當freeswitch使用outbound模式連接時,它將首先發一個CHANNEL_DATA事件,getInfo會返回該事件;
    在inbound模式中返回None

  • send(command)
    向freeswitch發送一個command,但不會等待返回結果,需要顯式調用recvEvent或recvEventTimed以接收返回的事件。

  • sendRecv(command)
    向freeswitch發送一個command,并等待返回結果(一個ESLevent對象)。

  • api(command[,arguments])
    向freeswitch發送api命令,阻塞執行

  • bgapi(command[, arguments][,custom_job_uuid])
    向freeswitch發送bgapi命令,后臺執行,非阻塞執行

  • sendEvent(event)
    向freeswitch發送一個事件

  • sendMSG(event,uuid)
    參考sendmsg命令

  • recvEvent()
    從freeswitch接收事件,阻塞模式

  • recvEventTimed(milliseconds)
    與recvEvent類似,但不會無限等待,而是在參數指定的毫秒數會返回。
    recvEventTimed(0)會立即返回。

  • filter (header,value)
    事件過濾,類似filter命令。

  • events (event_type,value)
    事件訂閱,類似event命令。

  • execute (app[,arg][,uuid])
    執行dialplan的app,并阻塞等待返回. 返回結果為一個ESLevent對象,通過getHeader(“Reply-Text”)可以獲取返回值,”+OK”表示成功,”-ERR”表示失敗。

  • executeAsync (app[,arg][,uuid])
    與execute()相同,但非阻塞執行。

  • setAsyncExecute(value)
    強制將socket設置為異步模式,value為1是異步,0是同步。

  • setEventLock(value)
    使用該選項后,后續所有的execute()調用都將帶有”event-lock:true”頭域。

  • disconnect()
    主動中斷與freeswitch的連接。

ESLevent對象

當接收一個事件時,用戶將獲得一個ESLevent對象,這個對象包含各種幫助函數變量 來幫助解析和處理收到的事件。

con = ESL.ESLconnection("127.0.0.1", "8021", "ClueCon") con.events("json", "all"); eventData = con.recvEvent()

eventData即為ESLevent對象

ESLevent對象成員函數列表如下:

  • serialize([format])?

    將event數據轉換成”name:value”型數據,format參數可以為:

    "xml"
    "json"
    "plain" (default)

    示例如下:

    eventData.serialize('json') 獲取json格式數據
  • setPriority([number])
    設置事件的級別
  • getHeader(headerName)
    獲取header對應的value,示例如下:

    eventData .getHeader('Event-Name') #獲取事件名稱

  • getBody()
    獲取事件的正文
  • getType()
    獲取event object的事件類型
  • addBody(value)
    向事件中加入正文,可以調用多次
  • addHeader(key,value)
    向事件中加入一個頭域(ESL_STACK_BOTTOM)
  • pushHeader(key,value)
    向事件中加入一個頭域(ESL_STACK_PUSH)
  • unshiftHeader(key,value)
    向事件中加入一個頭域(ESL_STACK_UNSHIFT)
  • delHeader(key)
    從Event中刪除頭域
  • firstHeader()
    將指針指向Event的第一個頭域,并返回它的key值。它必須在nextHeader之前調用
  • nextHeader()
    移動指針指向下一個header,在函數調用前必須先調用firstHeader()

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2016/20160926_freeswitch模塊之event_socket.md

歡迎補充??

轉載于:https://www.cnblogs.com/MikeZhang/p/freeswitch_mod_vent_socket_20160926.html

總結

以上是生活随笔為你收集整理的freeswitch模块之event_socket的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。