效果

每次用户注册,xml_curl模块都会向指定的 http 接口默认发起一个post请求,其中个包含注册的信息,如用户名,客户端信息等,但不包括密码,然后http接口返回一段 xml ,fs根据这段xml来校验,和直接配置在 conf/directory目录下的xml一样。

配置

编译模块

如果是源码编译,记得用这个命令 sed -i 's|#xml_int/mod_xml_curl|xml_int/mod_xml_curl|' /usr/src/freeswitch/build/modules.conf.in 取消注释,编译mod_xml_curl模块

启用模块

conf/autoload_configs/modules.conf.xml 开启<load module="mod_xml_curl"/>

配置模块

conf/autoload_configs/xml_curl.conf.xml 添加如下配置:

<binding name="directory"> 
          <param name="gateway-url" value="http://172.28.78.100:8888/fsapi" bindings="directory"/> 
     </binding> 

特别注意:buildingsbuilding 的嵌套关系,不要把上面的配置放到 building 标签内

编写 http 接口

任何服务端语言都可以,这里用 rust 作为例子。只要密码是123456都可以登录成功,密码可以从数据库读取

main.rs

use actix_web::{post, App, HttpResponse, HttpServer, Responder};
use std::collections::HashMap;

#[post("/fsapi")]
async fn fsapi(body: String) -> impl Responder {
    let mut params = HashMap::<&str, &str>::new();
    for (key, value) in body.split('&').map(|kv| {
        let mut kv = kv.split('=');
        (kv.next().unwrap(), kv.next().unwrap())
    }) {
        params.insert(key, value);
    }
    println!("params: {:#?}", params);

    let domain = params.get("domain").unwrap();
    let user = params.get("user").unwrap();

    let xml_str = format!(
        r#"<document type="freeswitch/xml">
  <section name="directory">
    <domain name="{}">
      <params>
        <param name="dial-string" value="{{presence_id=${{dialed_user}}@${{dialed_domain}}}}${{sofia_contact(${{dialed_user}}@${{dialed_domain}})}}"/>
      </params>
      <groups>
        <group name="default">
         <users>
          <user id="{}">
            <params>
              <param name="password" value="123456"/>
            </params>
          </user>
         </users>
        </group>
      </groups>
    </domain>
  </section>
</document>"#,
        domain, user
    );
    println!("xml_str: {}", xml_str);
    HttpResponse::Ok().body(xml_str)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| App::new().service(fsapi))
        .bind(("0.0.0.0", 8888))?
        .run()
        .await
}

Cargo.toml

[package]
name = "demo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = "4"

参考资料

https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod_xml_curl_1049001/#-binding-options-