FreeSwitcch(java使用)

FreeSwitcch安装(此处以Win系统为例)

转载:https://blog.csdn.net/angellee1988/article/details/101615596
安装地址:https://files.freeswitch.org/windows/installer/x64/(我安装的是1.10.7的)

FreeSwitcch配置

默认安装位置:C:\Program Files\FreeSWITCH

用户连接配置

可参照:https://blog.csdn.net/angellee1988/article/details/101615596的配置,

FreeSwitch默认设置了20个用户,如果需要更多的用户,那么只需要简单的三步就可以完成。
在conf/directory/default/中增加一个用户配置文件 修改拨号计划(Dialplan)使其它用户可以呼叫它
重新加载配置使其生效
要添加用户Jason,分机号是1020,只需要到conf/directory/default目录下,将1000.xml拷贝到1020.xml,然后打开1020.xml,将所有1000都改为1020,并把effective_caller_id_name的值改为Jason,然后保存退出。

如:

接下来,打开 conf/dialplan/default.xml,找到

<condition fied=“destionation_number” expression=“^(10[01][0-9]) $” >
行,将其改为:

<condition field=“destionation_number”
expresstion=“^(10[01][0-9]|1020) $” >

保存退出,回到控制台,然后执行reloadxml命令或按快捷键F6,使新的配置生效,那么新用户1020便添加成功。

freeSwitch的外呼配置

1.找到FreeSWITCH\conf\sip_profiles\internal.xml文件

//第133行左右将 <param name="local-network-acl" value="localnet.auto"/>
// 改为 <param name="local-network-acl" value="lan"/>
   <!-- <param name="local-network-acl" value="localnet.auto"/> -->
   <param name="local-network-acl" value="lan"/>

2.找到FreeSWITCH\conf\vars.xml文件
参考 :https://www.jianshu.com/p/84cc0c6d1d66

//约314行
  <X-PRE-PROCESS cmd="stun-set" data="external_sip_ip=你的ip"/>

3.找到FreeSWITCH\conf\autoload_configs\acl.conf.xml文件

//将12行-16行,改成如下
    <list name="lan" default="allow">
       <!--   <node type="deny" cidr="192.168.42.0/24"/> -->
        <!-- <node type="allow" cidr="192.168.42.42/32"/> -->
		 <node type="allow" cidr="0.0.0.0/0"/>
    </list>

FreeSwitcch使用

SIP软件的使用

https://www.microsip.org/downloads(软电话的软件)
在这里插入图片描述
可修改和配置用户
在这里插入图片描述

前端demo

下载地址:https://download.csdn.net/download/weixin_41922440/78129707
在这里插入图片描述

javaj和FreeSwitch连接(esl)

可参照:https://www.cnblogs.com/yjmyzz/p/freeswitch-esl-java-client-turorial.html

  • 包引入
<dependency>
    <groupId>org.freeswitch.esl.client</groupId>
    <artifactId>org.freeswitch.esl.client</artifactId>
    <version>0.9.2</version>
</dependency>
  • 主要程序连接
package com.cnblogs.yjmyzz.freeswitch.esl;
 
import org.freeswitch.esl.client.IEslEventListener;
import org.freeswitch.esl.client.inbound.Client;
import org.freeswitch.esl.client.inbound.InboundConnectionFailure;
import org.freeswitch.esl.client.transport.event.EslEvent;
 
/**
 * @author 菩提树下的杨过
 */
public class InboundApp {
    public static void main(String[] args) throws InterruptedException {
        Client client = new Client();
        try {
            //连接freeswitch
            client.connect("localhost", 8021, "ClueCon", 10);
 
            client.addEventListener(new IEslEventListener() {
 
                @Override
                public void eventReceived(EslEvent event) {
                    String eventName = event.getEventName();
                    //这里仅演示了CHANNEL_开头的几个常用事件
                    if (eventName.startsWith("CHANNEL_")) {
                        String calleeNumber = event.getEventHeaders().get("Caller-Callee-ID-Number");
                        String callerNumber = event.getEventHeaders().get("Caller-Caller-ID-Number");
                        switch (eventName) {
                            case "CHANNEL_CREATE":
                                System.out.println("发起呼叫, 主叫:" + callerNumber + " , 被叫:" + calleeNumber);
                                break;
                            case "CHANNEL_BRIDGE":
                                System.out.println("用户转接, 主叫:" + callerNumber + " , 被叫:" + calleeNumber);
                                break;
                            case "CHANNEL_ANSWER":
                                System.out.println("用户应答, 主叫:" + callerNumber + " , 被叫:" + calleeNumber);
                                break;
                            case "CHANNEL_HANGUP":
                                String response = event.getEventHeaders().get("variable_current_application_response");
                                String hangupCause = event.getEventHeaders().get("Hangup-Cause");
                                System.out.println("用户挂断, 主叫:" + callerNumber + " , 被叫:" + calleeNumber + " , response:" + response + " ,hangup cause:" + hangupCause);
                                break;
                            default:
                                break;
                        }
                    }
                }
 
                @Override
                public void backgroundJobResultReceived(EslEvent event) {
                    String jobUuid = event.getEventHeaders().get("Job-UUID");
                    System.out.println("异步回调:" + jobUuid);
                }
            });
 
            client.setEventSubscriptions("plain", "all");
 
            //这里必须检查,防止网络抖动时,连接断开
            if (client.canSend()) {
                System.out.println("连接成功,准备发起呼叫...");
                //(异步)向1000用户发起呼叫,用户接通后,播放音乐/tmp/demo1.wav
                String callResult = client.sendAsyncApiCommand("originate", "user/1000 &playback(/tmp/demo.wav)");
                System.out.println("api uuid:" + callResult);
            }
 
        } catch (InboundConnectionFailure inboundConnectionFailure) {
            System.out.println("连接失败!");
            inboundConnectionFailure.printStackTrace();
        }
         
    }
}

代码稍微解释一下:

a)18行,连接fs的用户名、密码、端口,可以在freeswitch安装目录下conf/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="loopback.auto"/>-->
    <!--<param name="stop-on-bind-error" value="true"/>-->
  </settings>
</configuration>

强烈建议,把第4行listen-ip改成0.0.0.0(或具体的本机ip地址),默认的::是ipv6格式,很多情况会导致esl
client连接失败,改成0.0.0.0相当于强制使用ipv4

b) 考虑到网络可能发生抖动,在发送命令前,建议参考60行的做法,先判断canSend()

c) 61行,client.sendAsyncApiCommand
这里以异步方式,发送了一个命令给fs(即:呼叫1000用户,接通后再放段声音)。异步方式下,命令是否发成功当时并不知道,但是这个方法会返回一个uuid的字符串,fs收到后,会在backgroundJobResultReceived回调中,把这个uuid再还回来,参见上面贴出的输出结果。(基于这个机制,可以做些重试处理,比如:先把uuid存下来,如果约定的时间内,uuid异步回调还没回来,可以视为发送失败,再发一次)

重要提示:esl java client
0.9.2这个版本,inbound模式下,长时间使用有内存泄露问题,网上有很多这个介绍及修复办法,建议生产环境使用前,先修改esl client的源码。

需要注意新用户的添加和SIP的开启,只有满足呼叫用户都是在用户列表中的,且被呼叫对象已经注册,才回呼叫成功
java后端动态生成用户的方法
需要注意的是,这个生成需要以管理员身份运行IDEA

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FreeSwitchUtils {

    public static void CreateFreeswitchUser(Long sipId) throws IOException, InterruptedException {
        String template = "C:\\Program Files\\FreeSWITCH\\conf\\directory\\default\\";
        String templateContent = read(template + "1000.xml");
        //创建指定用户
        String newUser =  StringUtils.leftPad(sipId + "", 3, '0');
        String newContent = templateContent.replaceAll("1000", newUser);
        String newFileName = template + newUser + ".xml";
        write(newFileName, newContent);
        System.out.println(newFileName + " done!");
    }

    static String read(String fileName) throws IOException {
        File f = new File(fileName);
        if (f.exists()) {
            FileInputStream fs = new FileInputStream(f);
            String result = null;
            byte[] b = new byte[fs.available()];
            fs.read(b);
            fs.close();
            result = new String(b);
            return result;
        } else {
            return null;
        }
    }

    static void write(String fileName, String fileContent) throws IOException {
        File f = new File(fileName);
        if (f.exists()) {
            f.delete();
        }
        FileOutputStream fs = new FileOutputStream(f);
        fs.write(fileContent.getBytes());
        fs.flush();
        fs.close();
    }
}

查看对象是否注册:sofia status profile internal reg

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值