当前位置: 首页 > news >正文

FreeSWITCH 之 chat

要把 FreeSWITCH 之 chat 完全研究清楚,似乎不容易

发送,路由,接收

跟哪些模块有关

等等

咱一边查资料,一边整理,不着急


先看看 Kamalio 怎么发 MESSAGE

loadmodule "uac.so"

route[uac_send_message] {
    $uac_req(method) = "MESSAGE";
    $uac_req(ruri) = "sip:10.0.1.5:5060";
    $uac_req(furi) = "sip:Emergency Alert";
    $uac_req(turi) = "sip:thisphone";
    # $uac_req(callid) = 
    $uac_req(hdrs) = "Subject: Emergency Alert\r\n";
    $uac_req(hdrs) = $uac_req(hdrs) + "Content-Type: text/plain\r\n";
    $uac_req(body) = "hi\r\n";
    $uac_req(evroute) = 1; # fire 路由,成功不成功,在路由块里面可以获取到
    uac_req_send();
}


event_route[uac:reply] {
	xinfo("===uac reply received, callid = $uac_req(callid), tu = $uac_req(turi), code = $uac_req(evcode)\n");
}

也可以设置 outbound proxy

$uac_req(ouri)  = "sip:1.2.3.4:5060";


现在来看看 FS 怎么发送 MESSAGE

当然,首先得加载 mod_sms


local event = freeswitch.Event("CUSTOM", "SMS::SEND_MESSAGE");
event:addHeader("proto", "sip");
event:addHeader("dest_proto", "sip");
event:addHeader("from", "1004@192.168.0.81");
event:addHeader("from_full", "sip:1004@192.168.0.81");
event:addHeader("to", "sip:1001@192.168.31.73:6666");
event:addHeader("subject", "12345678abcd");
event:addHeader("type", "text/plain");
event:addHeader("hint", "the hint");
event:addHeader("replying", "true");
event:addHeader("sip_profile", "internal");
event:addBody("Hi\r\n");
 
freeswitch.consoleLog("info", event:serialize());
event:fire();
 

如此就可以发送,目的地址是 sip:192.168.31.73:6666, 后者运行的是 MircoSIP, 配置文件里面设置 sourcePort=6666,会自动弹一个框出来,显示 `Hi`


fs_cli -x 'show chat'

show chat
type,name,ikey
chat,GLOBAL_SMS,mod_sms
chat,api,mod_dptools
chat,conf,mod_conference
chat,event,mod_dptools
chat,sip,mod_sofia
chat,verto,mod_verto

6 total.

哈哈,很清楚了

dest_proto 如果为 sip,那么 mod_sofia 来处理 chat 发送

dest_proto 如果为 verto,那么 mod_verto 来处理 chat 发送

以此类推,可以发到 会议,会议里面可以 chat, FS 的设计好牛


发送之后怎么看结果呢,怎么看 reply ?

答案是 SMS::DELIVERY_REPORT 子类,主键应该是 subject

下面是二个事件:

RECV EVENT
Event-Subclass: SMS::SEND_MESSAGE
Event-Name: CUSTOM
Core-UUID: b98d6556-a3cb-4b2b-8cca-a83386abbcfd
FreeSWITCH-Hostname: debian12
FreeSWITCH-Switchname: debian12
FreeSWITCH-IPv4: 192.168.31.213
FreeSWITCH-IPv6: ::1
Event-Date-Local: 2025-03-09 19:36:34
Event-Date-GMT: Sun, 09 Mar 2025 11:36:34 GMT
Event-Date-Timestamp: 1741520194385173
Event-Calling-File: switch_cpp.cpp
Event-Calling-Function: Event
Event-Calling-Line-Number: 315
Event-Sequence: 940
proto: sip
dest_proto: sip
from: 1004@192.168.0.81
from_full: sip:1004@192.168.0.81
to: sip:1001@192.168.31.73:6666
subject: 12345678abcd
type: text/plain
hint: the hint
replying: true
sip_profile: internal
skip_global_process: true
dest_proto: sip
Nonblocking-Delivery: true
skip_global_process: true
Content-Length: 4
Content-Length: 4

Hi

RECV EVENT
Event-Subclass: SMS::DELIVERY_REPORT
Event-Name: CUSTOM
Core-UUID: b98d6556-a3cb-4b2b-8cca-a83386abbcfd
FreeSWITCH-Hostname: debian12
FreeSWITCH-Switchname: debian12
FreeSWITCH-IPv4: 192.168.31.213
FreeSWITCH-IPv6: ::1
Event-Date-Local: 2025-03-09 19:36:34
Event-Date-GMT: Sun, 09 Mar 2025 11:36:34 GMT
Event-Date-Timestamp: 1741520194385173
Event-Calling-File: mod_sms.c
Event-Calling-Function: send_report
Event-Calling-Line-Number: 48
Event-Sequence: 941
Status: Accepted
Core-UUID: b98d6556-a3cb-4b2b-8cca-a83386abbcfd
FreeSWITCH-Hostname: debian12
FreeSWITCH-Switchname: debian12
FreeSWITCH-IPv4: 192.168.31.213
FreeSWITCH-IPv6: ::1
Event-Date-Local: 2025-03-09 19:36:34
Event-Date-GMT: Sun, 09 Mar 2025 11:36:34 GMT
Event-Date-Timestamp: 1741520194385173
Event-Calling-File: switch_cpp.cpp
Event-Calling-Function: Event
Event-Calling-Line-Number: 315
Event-Sequence: 940
proto: sip
dest_proto: sip
from: 1004@192.168.0.81
from_full: sip:1004@192.168.0.81
to: sip:1001@192.168.31.73:6666
subject: 12345678abcd
type: text/plain
hint: the hint
replying: true
sip_profile: internal
skip_global_process: true
dest_proto: sip
Nonblocking-Delivery: true
skip_global_process: true

请关注 subject 和 Status

另外,我目前测试的结果是,如果要获得准确的 Status,那么需要传 blocking 为 true,但我不确定我的测试结果是否 OK

请参考下面这段代码:

local event = freeswitch.Event("CUSTOM", "SMS::SEND_MESSAGE");
event:addHeader("proto", "sip");
event:addHeader("dest_proto", "sip");
event:addHeader("from", "1004@192.168.0.81");
event:addHeader("from_full", "sip:1004@192.168.0.81");
event:addHeader("to", "sip:1001@192.168.31.73:6666");
event:addHeader("subject", "12345678abcd");
event:addHeader("type", "text/plain");
event:addHeader("hint", "the hint");
event:addHeader("replying", "true");
event:addHeader("sip_profile", "internal");
event:addHeader("blocking", "true"); -- vip
event:addBody("Hi\r\n");
freeswitch.consoleLog("info", event:serialize());
event:fire();

把 MicroSIP 关闭掉

fs_cli 

console loglevel 0

/event plain all

运行上面的 lua 程序

过一会就能收到 DELIVERY_REPORT 事件,Status 为 Failure


要怎么设置 proxy呢?

笔者查了半天资料,终于找到了答案,可参考下面这个头:

contact-uri: sip:1002@192.168.0.99:11710;fs_path=sip:192.168.207.156:5060

重点是不要加 `<>`,加了就不好使

我查的资料讲的是发送 SIP NOTIFY 消息,那么发送SIP MESSAGE是否也如此

目前我还没进行测试

或者干脆增加 to_sip_ip 和 to_sip_port 参数


如何处理 chat 接收呢?

回答是 chatplan

我的习惯是先修改 sip profile, 增加一个 auth-messages = false 的配置,不然FS在收到 SIP MESSAGE 请求时会要求SIP 挑战,很麻烦

chatplan 里面能做什么?

mod_sms 有下面几个 app:

 show modules mod_sms

type,name,ikey,filename
application,final,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,fire,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,info,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,reply,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,send,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,set,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,stop,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,system,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
application,unset,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
chat,GLOBAL_SMS,mod_sms,/usr/local/freeswitch/mod/mod_sms.so
 

目前我没有一个一个进行研究

这是自带的 chatplan:

<?xml version="1.0" encoding="utf-8"?>
<include>
  <context name="default">
    <extension name="demo">
      <condition field="to" expression="^(.*)$">
	<!--	<action application="lua" data="test.lua"/> -->
	<action application="reply" data="Hello, you said: ${body}"/>
      </condition>
    </extension>
  </context>
</include>

 lua 要怎么写呢?

对象不再是 session, 而是 message, message 有哪些方法呢?

  • chat_send
  • chat_execute
  • setPriority
  • addBody
  • fire
  • getType
  • getHeader
  • addHeader
  • merge
  • serialize
  • getBody

下面是一个简单的 test.lua:

message:chat_execute("info")
message:chat_execute("final")

消息落地 ,不再转发,回 202


上面讲的是发送对话外 MESSAGE

那么对话内 MESSAGE 要怎么发送呢?

要研究下,除了 uuid_chat 是否还有别的?


mod_dptools 里面有个叫 chat 的 api, 很多资料都讲过了,这里不再赘述

其实弄了半天我发现自己还是没完全搞明白,以后再研究吧

相关文章:

  • 脏读、不可重复读,幻读的区别 mvcc及四种隔离级别
  • 2025年3家大牌云电脑游戏、AIGC大PK,最低0.1元,配置不再是问题
  • ⭐LeetCode(数学分类) 48. 旋转图像——优美的数学法转圈(原地修改)⭐
  • 《领导力21法则》第三章「过程法则」笔记
  • Sentinel-1 InSAR ISCE数据处理:stackSentinel.py 完全指南
  • 考研数学复习之拉格朗日中值定理求解函数极限
  • 深入链表操作:C语言中的链表中间节点查找与合并
  • 《Android 平台架构系统启动流程详解》
  • sparkTTS window 安装
  • MFC 项目:简易销售系统实践
  • MoonSharp 文档四
  • LLM学习之路-01-第一章-预训练/搞懂大模型的分词器(二)
  • electron builder打包时,出现errorOut=ERROR: Cannot create symbolic link
  • Talking Head Review (数字人算法综述)
  • Django 初始化导入数据详解
  • 数据结构:有序表的合并
  • Unity 扩散式布局
  • Unity 带阻尼感的转盘
  • 数智读书笔记系列015 探索思维黑箱:《心智社会:从细胞到人工智能,人类思维的优雅解读》读书笔记
  • Openlayer+天地图+山东天地图
  • 钟睒睒:不反对代工,但农夫山泉目前所有产品是无法代工的
  • 韩国第二大轮胎制造商因火灾停产,或影响700万条轮胎销售
  • 国家发改委:系统谋划7方面53项配套举措,推动民营经济促进法落地见效
  • 视频丨习近平在河南洛阳市考察调研
  • 上海蝉联全国中小企业发展环境评估综合排名第一
  • 肖钢:一季度证券业金融科技投资强度在金融各子行业中居首