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

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, 很多资料都讲过了,这里不再赘述

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

相关文章:

FreeSWITCH 之 chat

要把 FreeSWITCH 之 chat 完全研究清楚&#xff0c;似乎不容易 发送&#xff0c;路由&#xff0c;接收 跟哪些模块有关 等等 咱一边查资料&#xff0c;一边整理&#xff0c;不着急 先看看 Kamalio 怎么发 MESSAGE loadmodule "uac.so"route[uac_send_message] {…...

如何在Spring Boot中配置和使用MyBatis-Plus

在当今的Java开发中&#xff0c;Spring Boot已经成为了一个非常流行的框架&#xff0c;而MyBatis-Plus则是一个强大的ORM框架&#xff0c;为开发人员提供了更简便的数据库操作方式。很多开发者都在使用Spring Boot和MyBatis-Plus的组合来快速构建高效的应用。今天就来聊聊如何在…...

爱普生可编程晶振SG-8200CJ特性与应用

在高速发展的电子技术领域&#xff0c;时钟源作为电子系统的“心脏”&#xff0c;其性能直接影响设备的稳定性与可靠性。爱普生SG-8200CJ可编程晶振凭借其优秀的频率精度、低抖动性能及广泛的环境适应性&#xff0c;正成为众多领域的得力之选&#xff0c;为各类设备的高效运行与…...

ubuntu中用docker下载opengauss

1.安装docker sudo apt install docker.io2.拉取opengauss镜像 sudo docker pull enmotech/opengauss3.创建容器 sudo docker run --name opengauss --privilegedtrue -d -e GS_PASSWORDEnmo123 enmotech/opengauss:latest3.5.如果容器停止运行&#xff08;比如关机了&#…...

tslib

使用tslib来读取触摸屏的数据&#xff0c;可以得到原始数据&#xff0c;也可以在原始数据的基础上进行一些处理。比如有些触摸屏比较不稳定&#xff0c;跳动比较大&#xff0c;我们可以将跳动比较大的数据给删除掉 plugins里面的每个文件都会被编译成一个动态库&#xff0c;这些…...

MANUS怎么用

&#xff08;1&#xff09;分析方法论我过去说过一个分析模型&#xff1a;供给侧-消费侧。供给侧想做大&#xff0c;得靠生态集成。消费侧想坐大&#xff0c;得靠交互体验。&#xff08;2&#xff09;交互体验我先给大家讲一下计算机产业发展70来年&#xff0c;在交互上的变化。…...

Spring Cloud Alibaba 实战:Sentinel 保障微服务的高可用性与流量防护

1.1 Sentinel 作用 Sentinel 是阿里巴巴开源的一款 流量控制和熔断降级 框架&#xff0c;主要用于&#xff1a; 流量控制&#xff1a;限制 QPS&#xff0c;防止流量暴增导致系统崩溃熔断降级&#xff1a;当某个服务不可用时自动降级&#xff0c;避免故障扩散热点参数限流&…...

大数据技术在土地利用规划中的应用分析

大数据技术在土地利用规划中的应用分析 一、引言 土地利用规划是对一定区域内的土地开发、利用、整治和保护所作出的统筹安排与战略部署,对于实现土地资源的优化配置、保障社会经济的可持续发展具有关键意义。在当今数字化时代,大数据技术凭借其海量数据处理、高效信息挖掘等…...

MoonSharp 文档三

MoonSharp 文档一-CSDN博客 MoonSharp 文档二-CSDN博客 MoonSharp 文档四-CSDN博客 MoonSharp 文档五-CSDN博客 7.Proxy objects&#xff08;代理对象&#xff09; 如何封装你的实现&#xff0c;同时又为脚本提供一个有意义的对象模型 官方文档&#xff1a;MoonSharp 在实际…...

linux和windows之间的复制

第一步 sudo apt-get autoremove open-vm-tools第二步 sudo apt-get update第三步 sudo apt-get install open-vm-tools-desktop按y 第四步 重启虚拟机&#xff0c;终端下输入 rebootLinux下 按“ CtrlShiftC V ”复制粘贴 Windows下按“ Ctrl C V ”复制粘贴...

在资源有限中逆势突围:从抗战智谋到寒门高考的破局智慧

目录 引言 一、历史中的非对称作战&#xff1a;从李牧到八路军的智谋传承 李牧戍边&#xff1a;古代军事博弈中的资源重构 八路军的游击战&#xff1a;现代战争中的智慧延续 二、创业界的逆袭之道&#xff1a;小米与拼多多的资源重构 从MVP到杠杆解 社交裂变与资源错配 …...

Ubuntu 22.04 无法进入图形界面的解决方法

Ubuntu 22.04 无法进入图形界面&#xff0c;只能进入 tty&#xff0c;可能是由于图形界面相关的配置或驱动程序出现了问题。以下是一些常见的解决方法&#xff1a; 1. 检查图形界面服务状态 首先&#xff0c;检查图形界面服务&#xff08;通常是 gdm 或 lightdm&#xff09;的…...

Python中很常用的100个函数整理

Python 内置函数提供了强大的工具&#xff0c;涵盖数据处理、数学运算、迭代控制、类型转换等。本文总结了 100 个常用内置函数&#xff0c;并配备示例代码&#xff0c;提高编程效率。 1. abs() 取绝对值 print(abs(-10)) # 10 2. all() 判断所有元素是否为真 print(all([…...

javascript-es6 (六)

编程思想 面向过程 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次 调用就可以了 就是按照我们分析好了的步骤&#xff0c;按照步骤解决问题 面向对象 面向对象是把事务分解成为一个个对象&…...

大模型微调技术基础(一)

文章目录 GPT与BERT的差异GPT&#xff08;Decoder架构&#xff09;优点缺点 BERT&#xff08;Encoder架构&#xff09;优点缺点 总结 LoRA低参数大模型与全参数小模型表现对比分析LoRA&#xff08;Low-Rank Adaptation&#xff09;技术详解1. LoRA 核心原理2. 应用场景3. 简单代…...

Spring AI 1.0.0 M6新特性MCP

Spring AI 1.0.0 M6新特性MCP 前言一、MCP是什么&#xff1f;&#xff08;Model Context Protocol&#xff09;二、它的发展历程三、核心架构四、MCP Java SDK的核心能力Java MCP实现遵循三层架构&#xff1a;MCP客户端MCP服务器总结MCP 的核心能力总结多种传输选项 搭建服务端…...

【时时三省】(C语言基础)赋值表达式和赋值语句和变量赋初值

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 赋值表达式和赋值语句 在C程序中&#xff0c;赋值语句是用得最多的语句。实际上&#xff0c;C语言的赋值语句属于表达式语句&#xff0c;由一个赋值表达式加一个分号组成。其他一些高级语言…...

Room数据库的使用

一、room的引用导入 1、在app的gradle中引入 plugins {//这个ksp 一定要对应相关的 kotlin 版本&#xff0c;不然会一直报错i的---id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false } 2、在model的gradle中引入 plugins {id("com.g…...

【性能测试入门_01性能测试jmeter基础实操场景详解】

一、应用项目如何部署在服务器上 可以将项目进行打jar包 双击install&#xff0c;控制台就会打印打包的过程 最终打的包&#xff0c;会存放在打印的那个路径下 这个jar包&#xff0c;就是开发人员开发好&#xff0c;直接可以部署的 可以通过命令&#xff0c;在终端直接启动这…...

SpringBoot加载配置文件的优先级

在 SpringBoot 应用中&#xff0c;配置文件的加载顺序&#xff08;优先级&#xff09;决定了不同来源的配置属性如何覆盖彼此&#xff0c;但是&#xff0c;在实践中&#xff0c;也会经常遇到。下面文章将分析 SpringBoot 配置文件加载的优先级&#xff0c;从高到低排列。 文章目…...

跨越时空的对话:图灵与GPT-4聊AI的前世今生

&#xff08;背景&#xff1a;虚拟咖啡厅&#xff0c;图灵身着1950年代西装&#xff0c;端着一杯热茶&#xff0c;GPT-4以全息投影形态坐在对面&#xff09; 图灵&#xff08;喝了口茶&#xff09;&#xff1a;“听说你能写诗&#xff1f;我当年在布莱切利园破解Enigma时&…...

如何通过 Seatunnel 实现 MySQL 到 OceanBase的数据迁移同步

1. 准备传输工具 本方案采用 Apache Seatunnel&#xff08;简称seatunnel&#xff09;进行MySQL 到 OceanBase 的数据迁移和同步&#xff0c;出于对方案轻量性的考量&#xff0c;我们采用其内置的Zeta引擎来实现&#xff0c;包括全量同步、离线增量同步&#xff0c;以及CDC方案…...

C++20 新特性总结

简要总结 C20 引入了四项非常大的更新, 分别是: 概念(Concepts). 用来简化模板编程, 强化表达能力. 并且使得出错原因更容易查找.模块(Modules). 这是代码组织方面非常大的更新. 提供了新的方式来组织代码, 并且可以减少编译时间.范围库(Ranges and Views). 轻量级的, 非拥有…...

软件设计模式之简单工厂模式

目录 一.类图&#xff08;手机生产&#xff09; 二.代码实现 Iphone类&#xff1a; Vivo类&#xff1a; Mobile类&#xff1a; MobileFactory类&#xff1a; Client类&#xff1a; 一.类图&#xff08;手机生产&#xff09; 补充&#xff1a;MobileFactory也可以直接指向…...

内网激活JRebel插件(无网络环境)

1.官网下载安装包,JRebel and XRebel JRebel and XRebel - IntelliJ IDEs Plugin | Marketplace 2.以IInstall Plugin from Disk的方式读取 3.运行JrebelServer.jar 终端输入&#xff1a; java -jar JrebelServer.jar -p 8080 (默认8080端口)服务会自动打开浏览器至 http:/…...

LiveGBS流媒体平台GB/T28181常见问题-视频流安全控制HTTP接口鉴权勾选流地址鉴权后401Unauthorized如何播放调用接口流地址校验

LiveGBS流媒体平台GB/T28181常见问题频流安全控制HTTP接口鉴权勾选流地址鉴权后401Unauthorized如何播放调用接口流地址校验&#xff1f; 1、安全控制1.1、HTTP接口鉴权1.2、流地址鉴权 2、401 Unauthorized2.1、携带token调用接口2.1.1、获取鉴权token2.1.2、调用其它接口2.1.…...

Java 大视界 -- 区块链赋能 Java 大数据:数据可信与价值流转(84)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

接口自动化入门 —— Http的请求头,请求体,响应码解析!

在接口自动化测试中&#xff0c;HTTP请求头、请求体和响应码是核心组成部分。理解它们的作用、格式和解析方法对于进行有效的接口测试至关重要。以下是详细解析&#xff1a; 1. HTTP 请求头&#xff08;Request Header&#xff09; 1.1 作用 请求头是客户端向服务器发送的附加…...

upload-labs(1-20)详解(专业版)

目录 第1关 第2关 第3关 第4题 第5题 第6题 第7题 第8题 第9题 第10题 第11题 第12题 第13题 第1关 查看源码 在第一关是一个前端js的一个后缀识别&#xff1a;当不为jpg、png、gif时候出现弹窗 检查源码 将return checkFile() 改为 return ture 就可以将php顺利…...

Linux 生成静态库

文章目录 前提小知识生成和使用.a库操作步骤 在应用程序中&#xff0c;有一些公共的代码需要反复使用的&#xff0c;可以把这些代码制作成“库文件”&#xff1b;在链接的步骤中&#xff0c;可以让链接器在“库文件”提取到我们需要使用到的代码&#xff0c;复制到生成的可执行…...