Class: Freeswitch::ESL::Connection::MessageReader

Inherits:
Object
  • Object
show all
Defined in:
lib/freeswitch/esl/connection/message_reader.rb

Overview

Reads ESL protocol messages from the socket and routes them appropriately. Runs in a dedicated thread and handles socket parsing and message dispatch.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(socket, event_dispatcher, &on_disconnect_callback) ⇒ MessageReader

Returns a new instance of MessageReader.



11
12
13
14
15
16
17
# File 'lib/freeswitch/esl/connection/message_reader.rb', line 11

def initialize(socket, event_dispatcher, &on_disconnect_callback)
  @socket = socket
  @event_dispatcher = event_dispatcher
  @on_disconnect_callback = on_disconnect_callback
  @response_queue = Queue.new
  @reader_thread = nil
end

Instance Attribute Details

#response_queueObject (readonly)

Get the response queue (where command replies are enqueued).



20
21
22
# File 'lib/freeswitch/esl/connection/message_reader.rb', line 20

def response_queue
  @response_queue
end

Instance Method Details

#enqueue_error(error) ⇒ Object

Enqueue an error to unblock waiting threads (e.g., on disconnect).



63
64
65
# File 'lib/freeswitch/esl/connection/message_reader.rb', line 63

def enqueue_error(error)
  @response_queue << error
end

#receive_response(timeout:) ⇒ Object

Wait for and return a response from the response queue with timeout.



52
53
54
55
56
57
58
59
60
# File 'lib/freeswitch/esl/connection/message_reader.rb', line 52

def receive_response(timeout:)
  result = nil
  Timeout.timeout(timeout) { result = @response_queue.pop }
  raise result if result.is_a?(Exception)

  result
rescue Timeout::Error
  raise TimeoutError, "Command timed out after #{timeout}s — connection closed"
end

#startObject

Start the reader thread.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/freeswitch/esl/connection/message_reader.rb', line 23

def start
  return if @reader_thread

  @reader_thread = Thread.new do
    loop do
      msg = read_message
      unless msg
        on_disconnect(DisconnectedError.new("Connection closed by remote host"))
        break
      end

      route_message(msg)
    rescue IOError, Errno::ECONNRESET, Errno::ENOTCONN => e
      on_disconnect(DisconnectedError.new(e.message))
      break
    end
  end
  @reader_thread.name = "esl-reader"
  @reader_thread.abort_on_exception = false
end

#stopObject

Stop the reader thread and join it.



45
46
47
48
49
# File 'lib/freeswitch/esl/connection/message_reader.rb', line 45

def stop
  # The thread exits when socket reads hit EOF/error. `stop` is only a
  # synchronisation point to wait for clean shutdown.
  @reader_thread&.join
end