# zhouhailin/freeswitch-externals architecture

> Architecture diagram of the GitHub repository zhouhailin/freeswitch-externals, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/zhouhailin/freeswitch-externals
- Repository: https://github.com/zhouhailin/freeswitch-externals

## Overview

This repository provides a Java FreeSWITCH Event Socket Layer (ESL) client plus a Spring Boot starter. Its main workflow configures one or more FreeSWITCH servers, creates and starts an inbound client, connects over Netty, then exchanges commands and delivers parsed events to listeners or handlers. The README also documents cluster connections and dynamic server add/remove. Source excerpts establish some runtime calls; starter auto-wiring and several implementation details are represented only where the README documents them.

Main entry points: [`freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClient.java`](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClient.java) (Inbound client API), [`freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java`](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java) (Channel handler), [`freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java`](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java) (Client lifecycle), [`freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/InboundClientOption.java`](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/InboundClientOption.java) (Client options)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_spring["Spring Boot Starter"]
  node_spring_props["Starter properties"]
  node_spring_autoconfig["Auto-configuration"]
  node_option_handler["Option handler"]
  node_event_handlers["Event handlers"]
  node_listener_templates["Listener templates"]
end

subgraph group_client["Client Configuration"]
  node_client_api["Inbound client API<br/>[InboundClient.java]"]
  node_factory["Client factory"]
  node_client_options["Client options"]
  node_server_options["Server options<br/>[ServerOption.java]"]
end

subgraph group_connection["Connection Runtime"]
  node_client_runtime["Client lifecycle"]
  node_netty_client["Netty client"]
  node_channel_handler["Channel handler"]
  node_connection_listener["Connection listener"]
end

subgraph group_protocol["ESL Protocol"]
  node_frame_decoder["Frame decoder"]
  node_esl_message["ESL message<br/>[EslMessage.java]"]
  node_esl_event["Event parser<br/>[EslEvent.java]"]
  node_command_response["Command response"]
  node_event_listener["ESL event listener"]
end

node_developer(("Application developer"))
node_freeswitch(("FreeSWITCH server"))

node_developer -->|"sets properties"| node_spring_props
node_spring_props -->|"builds options"| node_option_handler
node_option_handler -->|"creates options"| node_client_options
node_spring_autoconfig -.->|"configures starter"| node_client_api
node_client_api -->|"creates client"| node_factory
node_factory -->|"instantiates"| node_netty_client
node_client_api -->|"uses options"| node_client_options
node_client_options -->|"stores servers"| node_server_options
node_client_api -.->|"starts client"| node_client_runtime
node_client_runtime -->|"reads options"| node_client_options
node_client_runtime -->|"manages connections"| node_server_options
node_client_runtime -->|"closes handlers"| node_channel_handler
node_netty_client -->|"sends commands"| node_channel_handler
node_freeswitch -.->|"sends ESL frames"| node_channel_handler
node_channel_handler -->|"handles messages"| node_esl_message
node_frame_decoder -->|"decodes frames"| node_esl_message
node_esl_event -->|"parses message"| node_esl_message
node_channel_handler -->|"dispatches events"| node_esl_event
node_channel_handler -->|"calls listener"| node_event_listener
node_netty_client -->|"returns responses"| node_command_response
node_event_listener -.->|"adapts events"| node_event_handlers
node_developer -->|"uses API"| node_client_api
node_connection_listener -.->|"reports state"| node_developer
node_client_api -->|"adds or removes"| node_server_options

click node_spring_props "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/properties/InboundClientProperties.java"
click node_spring_autoconfig "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/config/FreeswitchEslAutoConfiguration.java"
click node_option_handler "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/AbstractInboundClientOptionHandler.java"
click node_event_handlers "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/DefaultEslEventHandler.java"
click node_listener_templates "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/template/IEslEventListenerTemplate.java"
click node_client_api "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClient.java"
click node_factory "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClientFactory.java"
click node_client_options "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/InboundClientOption.java"
click node_server_options "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/ServerOption.java"
click node_client_runtime "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java"
click node_netty_client "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/NettyInboundClient.java"
click node_channel_handler "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java"
click node_connection_listener "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/ServerConnectionListener.java"
click node_frame_decoder "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/message/EslFrameDecoder.java"
click node_esl_message "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/message/EslMessage.java"
click node_esl_event "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/event/EslEvent.java"
click node_command_response "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/CommandResponse.java"
click node_event_listener "https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/IEslEventListener.java"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_spring_props,node_spring_autoconfig,node_option_handler,node_event_handlers,node_listener_templates toneBlue
class node_client_api,node_factory,node_client_options,node_server_options toneAmber
class node_client_runtime,node_netty_client,node_channel_handler,node_connection_listener,node_freeswitch toneMint
class node_frame_decoder,node_esl_message,node_esl_event,node_command_response,node_event_listener toneRose
class node_developer toneIndigo
```

## Components

### Spring Boot Starter

- [Starter properties](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/properties/InboundClientProperties.java): `freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/properties/InboundClientProperties.java`
- [Auto-configuration](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/config/FreeswitchEslAutoConfiguration.java): `freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/config/FreeswitchEslAutoConfiguration.java`
- [Option handler](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/AbstractInboundClientOptionHandler.java): `freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/AbstractInboundClientOptionHandler.java`
- [Event handlers](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/DefaultEslEventHandler.java): `freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/DefaultEslEventHandler.java`
- [Listener templates](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/template/IEslEventListenerTemplate.java): `freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/template/IEslEventListenerTemplate.java`

### Client Configuration

- [Inbound client API](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClient.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClient.java`
- [Client factory](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClientFactory.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClientFactory.java`
- [Client options](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/InboundClientOption.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/InboundClientOption.java`
- [Server options](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/ServerOption.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/ServerOption.java`

### Connection Runtime

- [Client lifecycle](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java`
- [Netty client](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/NettyInboundClient.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/NettyInboundClient.java`
- [Channel handler](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java`
- [Connection listener](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/ServerConnectionListener.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/ServerConnectionListener.java`

### ESL Protocol

- [Frame decoder](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/message/EslFrameDecoder.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/message/EslFrameDecoder.java`
- [ESL message](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/message/EslMessage.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/message/EslMessage.java`
- [Event parser](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/event/EslEvent.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/event/EslEvent.java`
- [Command response](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/CommandResponse.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/CommandResponse.java`
- [ESL event listener](https://github.com/zhouhailin/freeswitch-externals/blob/v2-dev/freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/IEslEventListener.java): `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/IEslEventListener.java`

### Other components

- **Application developer**
- **FreeSWITCH server**

## Connections

- Application developer → Starter properties: sets properties (evidence: `README.md`)
- Starter properties → Option handler: builds options (evidence: `freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/AbstractInboundClientOptionHandler.java`)
- Option handler → Client options: creates options (evidence: `freeswitch-esl-spring-boot-starter/src/main/java/link/thingscloud/freeswitch/esl/spring/boot/starter/handler/AbstractInboundClientOptionHandler.java`)
- Auto-configuration → Inbound client API: configures starter (evidence: `README.md`)
- Inbound client API → Client factory: creates client (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClient.java`)
- Client factory → Netty client: instantiates (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClientFactory.java`)
- Inbound client API → Client options: uses options (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/InboundClient.java`)
- Client options → Server options: stores servers (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/option/InboundClientOption.java`)
- Inbound client API → Client lifecycle: starts client (evidence: `README.md`)
- Client lifecycle → Client options: reads options (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java`)
- Client lifecycle → Server options: manages connections (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java`)
- Client lifecycle → Channel handler: closes handlers (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/AbstractInboundClient.java`)
- Netty client → Channel handler: sends commands (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/NettyInboundClient.java`)
- FreeSWITCH server → Channel handler: sends ESL frames
- Channel handler → ESL message: handles messages (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java`)
- Frame decoder → ESL message: decodes frames (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/message/EslMessage.java`)
- Event parser → ESL message: parses message (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/transport/event/EslEvent.java`)
- Channel handler → Event parser: dispatches events (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java`)
- Channel handler → ESL event listener: calls listener (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/handler/InboundChannelHandler.java`)
- Netty client → Command response: returns responses (evidence: `freeswitch-esl/src/main/java/link/thingscloud/freeswitch/esl/inbound/NettyInboundClient.java`)
- ESL event listener → Event handlers: adapts events (evidence: `README.md`)
- Application developer → Inbound client API: uses API (evidence: `README.md`)
- Connection listener → Application developer: reports state (evidence: `README.md`)
- Inbound client API → Server options: adds or removes (evidence: `README.md`)
