1.x under development, JDK 1.8, spring boot 2.x
2.x under development, JDK 17, spring boot 3.x (v2.x-dev)
Netty used 4.1.x, 5.x is not supported
1. Support to connect FreeSWITCH Cluster
2. Easy to integrate with FreeSWITCH ESL
3. Support spring boot starter
4. Support to dynamic add or remove remote server
<dependency>
<groupId>link.thingscloud</groupId>
<artifactId>freeswitch-esl</artifactId>
<version>${freeswitch-esl.version}</version>
</dependency>
<dependency>
<groupId>link.thingscloud</groupId>
<artifactId>freeswitch-esl-spring-boot-starter</artifactId>
<version>${freeswitch-esl.version}</version>
</dependency>
application.properties
link.thingscloud.freeswitch.esl.inbound.servers[0].host=127.0.0.1
link.thingscloud.freeswitch.esl.inbound.servers[0].port=8021
link.thingscloud.freeswitch.esl.inbound.servers[0].timeout-seconds=5
link.thingscloud.freeswitch.esl.inbound.servers[0].password=ClueCon
link.thingscloud.freeswitch.esl.inbound.servers[2].host=127.0.0.2
link.thingscloud.freeswitch.esl.inbound.servers[2].port=8021
link.thingscloud.freeswitch.esl.inbound.servers[2].timeout-seconds=5
link.thingscloud.freeswitch.esl.inbound.events=CHANNEL_CREATE CHANNEL_DESTROY
# performance monitor - event driven - business logic processing time
link.thingscloud.freeswitch.esl.inbound.performance=true
link.thingscloud.freeswitch.esl.inbound.performanceCostTime=200
# event performance monitor - event driven - event generate time and event receive time
link.thingscloud.freeswitch.esl.inbound.eventPerformance=false
link.thingscloud.freeswitch.esl.inbound.eventPerformanceCostTime=200
application.yml
link:
thingscloud:
freeswitch:
esl:
inbound:
defaultPassword: ClueCon
performance: false
performanceCostTime: 200
#read-timeout-seconds: 0
servers:
- host: 127.0.0.1
port: 8021
timeoutSeconds: 5
- host: 127.0.0.2
- host: 127.0.0.3
events:
- CHANNEL_CREATE
- CHANNEL_DESTROY
@Slf4j
@Component
public class ExampleInboundClient {
@Autowired
private InboundClient inboundClient;
@Autowired
private InboundClientBootstrap inboundClientBootstrap;
@PostConstruct
public void startup() {
System.out.println(inboundClientBootstrap);
}
}
@Slf4j
@Component
public class InboundClientOptionHandlerExample extends AbstractInboundClientOptionHandler {
/**
* {@inheritDoc}
*/
@Override
protected void intercept(InboundClientOption inboundClientOption) {
List<ServerOption> serverOptions = inboundClientOption.serverOptions();
log.info("serverOptions before : {}", serverOptions);
serverOptions.clear();
serverOptions.add(new ServerOption("127.0.0.8", 8021));
log.info("serverOptions after : {}", serverOptions);
}
}
@Slf4j
@Component
@EslEventName(EventNames.HEARTBEAT)
public class HeartbeatEslEventHandler implements EslEventHandler {
/**
* {@inheritDoc}
*/
@Override
public void handle(String addr, EslEvent event) {
log.info("HeartbeatEslEventHandler handle addr[{}] EslEvent[{}].", addr, event);
}
}
@Slf4j
@Service
public class ServerConnectionListenerImpl implements ServerConnectionListener {
/**
* {@inheritDoc}
*/
@Override
public void onOpened(ServerOption serverOption) {
log.info("onOpened serverOption : {}", serverOption);
}
/**
* {@inheritDoc}
*/
@Override
public void onClosed(ServerOption serverOption) {
log.info("onClosed serverOption : {}", serverOption);
}
}
<dependency>
<groupId>link.thingscloud</groupId>
<artifactId>freeswitch-esl</artifactId>
<version>${freeswitch-esl.version}</version>
</dependency>
InboundClientOption option = new InboundClientOption();
// set default esl password, if ServerOption not set password, use this default value
option.defaultPassword("ClueCon")
.addServerOption(new ServerOption("127.0.0.1", 8021));
// set esl subscribe events
option.addEvents("all");
// ESL event listener
option.addListener(new IEslEventListener() {
@Override
public void eventReceived(String addr, EslEvent event) {
System.out.println(addr);
System.out.println(event);
}
@Override
public void backgroundJobResultReceived(String addr, EslEvent event) {
System.out.println(addr);
System.out.println(event);
}
});
option.serverConnectionListener(new ServerConnectionListener() {
@Override
public void onOpened(ServerOption serverOption) {
System.out.println("---onOpened--");
}
@Override
public void onClosed(ServerOption serverOption) {
System.out.println("---onClosed--");
}
});
InboundClient inboundClient = InboundClient.newInstance(option);
// start client
inboundClient.start();
// shutdown client, after shutdown, can't start again, shutdown with JVM
inboundClient.shutdown();
// Get InboundClient Instance
InboundClient inboundClient = InboundClient.getInstance();
// Get InboundClient FreeSWITCH API
InboundClient.getBootstrap()
// add server option
inboundClient.option().addServerOption(new ServerOption(host, port));
// InboundClient.getInstance().option().addServerOption(new ServerOption(host, port));
// remove server option
ServerOption serverOption = inboundClient.option().serverOptions().get(0);
inboundClient.option().removeServerOption(serverOption);
// InboundClient.getInstance().option().removeServerOption(serverOption);
1. Send api is recommended to use asynchronous operation, especially the originate command
2. There is a message timeout mechanism at present to deal with the false death of the connection caused by the direct shutdown of the server. Set the value of readTimeoutSeconds parameter to 0 to turn off this feature
3. In order to improve performance, when processing EslEvent, use Netty's worker thread. If the processing logic involves IO or time-consuming operation, the processing logic must be put in a new thread to process, and the disablePublicExecutor parameter is set
Apache License, Version 2.0 Copyright (C) Apache Software Foundation