Class: Freeswitch::ESL::Connection
- Inherits:
-
Object
- Object
- Freeswitch::ESL::Connection
- Includes:
- Logger
- Defined in:
- lib/freeswitch/esl/connection.rb,
lib/freeswitch/esl/connection/command_request.rb,
lib/freeswitch/esl/connection/event_dispatcher.rb,
lib/freeswitch/esl/connection/command_dispatcher.rb
Overview
Base ESL connection that handles the wire protocol.
Subclasses are responsible for providing an open socket and calling #initialize_socket to start the reader and event-dispatcher threads.
Threading model:
* A reader thread owned by {CommandDispatcher} reads messages from the
socket and routes them to pending command executions (FIFO) or to the
event dispatcher.
* A *dispatcher thread* processes @event_queue and calls registered handlers.
* Command enqueue + write is atomic under a mutex in CommandDispatcher,
guaranteeing queue order == socket write order.
Direct Known Subclasses
Defined Under Namespace
Classes: CommandDispatcher, CommandRequest, EventDispatcher
Instance Method Summary collapse
-
#bgapi(command, *args, timeout: nil, &block) ⇒ Object
Execute a background
bgapicommand. -
#close ⇒ Object
Stop dispatchers and mark the connection closed.
- #closed? ⇒ Boolean
-
#filter(header, value) ⇒ Object
Add an event-header filter so FreeSWITCH only sends matching events.
-
#initialize(socket) ⇒ Connection
constructor
A new instance of Connection.
-
#on(event_name) ⇒ Object
Register a handler block for an event name.
-
#pending_bgapi_command_uuids ⇒ Object
Return an array of Job-UUID strings for all pending bgapi commands.
-
#pending_commands_count ⇒ Object
Return the number of commands currently waiting for a response.
-
#send_command(command, timeout: nil) ⇒ Object
Send a raw ESL command and return a CommandRequest object that can be used to wait for the response.
-
#subscribe(*event_names) ⇒ Object
Subscribe to one or more event names (JSON format).
-
#unsubscribe(*event_names) ⇒ Object
Cancel subscriptions.
Methods included from Logger
Constructor Details
#initialize(socket) ⇒ Connection
Returns a new instance of Connection.
28 29 30 |
# File 'lib/freeswitch/esl/connection.rb', line 28 def initialize(socket) initialize_socket(socket) end |
Instance Method Details
#bgapi(command, *args, timeout: nil, &block) ⇒ Object
Execute a background bgapi command. Returns the Job-UUID string. The optional block is called with the BACKGROUND_JOB Event when the result arrives.
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/freeswitch/esl/connection.rb', line 42 def bgapi(command, *args, timeout: nil, &block) raise DisconnectedError, "Connection is closed" if closed? parts = ["bgapi", command, *args].compact logger.debug("[BGAPI] #{parts.join(' ')}") cmd = @command_dispatcher.execute_command(parts.join(" "), timeout:).wait job_uuid = cmd.response["Job-UUID"] raise CommandError, "FreeSWITCH bgapi did not return a Job-UUID" unless job_uuid @event_dispatcher.register_bgapi_handler(job_uuid, block) if block job_uuid end |
#close ⇒ Object
Stop dispatchers and mark the connection closed. Event handlers are removed together with the dispatcher instances, so a reconnect path must rebuild them through #initialize_socket.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/freeswitch/esl/connection.rb', line 101 def close return if @closed @closed = true @command_dispatcher&.stop @event_dispatcher&.stop send(:remove_instance_variable, :@command_dispatcher) send(:remove_instance_variable, :@event_dispatcher) end |
#closed? ⇒ Boolean
94 95 96 |
# File 'lib/freeswitch/esl/connection.rb', line 94 def closed? @closed end |
#filter(header, value) ⇒ Object
Add an event-header filter so FreeSWITCH only sends matching events.
82 83 84 |
# File 'lib/freeswitch/esl/connection.rb', line 82 def filter(header, value) send_command("filter #{header} #{value}").wait end |
#on(event_name) ⇒ Object
Register a handler block for an event name. Use “ALL” to handle every event. Multiple handlers per event name are supported. Returns self for chaining.
89 90 91 92 |
# File 'lib/freeswitch/esl/connection.rb', line 89 def on(event_name, &) @event_dispatcher.on(event_name, &) self end |
#pending_bgapi_command_uuids ⇒ Object
Return an array of Job-UUID strings for all pending bgapi commands.
61 62 63 |
# File 'lib/freeswitch/esl/connection.rb', line 61 def pending_bgapi_command_uuids @event_dispatcher.pending_bgapi_command_uuids end |
#pending_commands_count ⇒ Object
Return the number of commands currently waiting for a response.
56 57 58 |
# File 'lib/freeswitch/esl/connection.rb', line 56 def pending_commands_count @command_dispatcher.pending_commands_count end |
#send_command(command, timeout: nil) ⇒ Object
Send a raw ESL command and return a CommandRequest object that can be used to wait for the response.
33 34 35 36 37 |
# File 'lib/freeswitch/esl/connection.rb', line 33 def send_command(command, timeout: nil) raise DisconnectedError, "Connection is closed" if closed? @command_dispatcher.execute_command(command, timeout:) end |
#subscribe(*event_names) ⇒ Object
Subscribe to one or more event names (JSON format). Pass no arguments or “ALL” to receive every event.
67 68 69 70 |
# File 'lib/freeswitch/esl/connection.rb', line 67 def subscribe(*event_names) events = event_names.empty? ? "ALL" : event_names.join(" ") send_command("event json #{events}").wait end |
#unsubscribe(*event_names) ⇒ Object
Cancel subscriptions. Without arguments cancels all events.
73 74 75 76 77 78 79 |
# File 'lib/freeswitch/esl/connection.rb', line 73 def unsubscribe(*event_names) if event_names.empty? send_command("noevents").wait else event_names.each { |e| send_command("nixevent #{e}").wait } end end |