librevox 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/lib/librevox/command_socket.rb +15 -5
- data/lib/librevox/listener/base.rb +4 -8
- data/lib/librevox/listener/inbound.rb +4 -4
- data/lib/librevox/listener/outbound.rb +7 -14
- data/lib/librevox/protocol/connection.rb +2 -2
- data/lib/librevox/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 741f63e510f82a40cfbb818d889405e46327bda536843c891767d21fafc7032d
|
|
4
|
+
data.tar.gz: be1b2346b673120f343d2cfea7c6eb71fcc085a3e1bdcdcaa86989dd97705b8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77ed21f1951ea0061315850c0222ac422bedd25baa1e18b3e73bc983d9be1cfd94c6d3f9628ddc2e1461405d6623c248bd72e2a9a2bb1f898df035b0303962ed
|
|
7
|
+
data.tar.gz: 53fde0404e9b427820018c805d15f1bbb65fe9108384db699702130fb6c0aecefd89a3865e06193b75a5bc04fb06e7d47957e3e179f80f0f16a1edd414e479be
|
data/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/banner.svg" alt="Librevox" width="100%">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# Librevox
|
|
2
6
|
|
|
3
7
|
A Ruby library for interacting with [FreeSWITCH](http://www.freeswitch.org) through [mod_event_socket](https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod_event_socket_1048924/), using async I/O.
|
|
@@ -267,12 +271,12 @@ being processed until the current application completes.
|
|
|
267
271
|
Librevox runs two fibers for each outbound connection:
|
|
268
272
|
|
|
269
273
|
- **Session fiber** (`run_session`) — runs the setup sequence and then
|
|
270
|
-
`session_initiated`. Each `
|
|
274
|
+
`session_initiated`. Each `send_message` or `application` call blocks the fiber
|
|
271
275
|
until the reply arrives.
|
|
272
276
|
- **Read fiber** (`read_loop`) — reads messages from the socket and dispatches
|
|
273
277
|
them to `Async::Queue` instances, waking the session fiber.
|
|
274
278
|
|
|
275
|
-
An `Async::Semaphore(1)` mutex on `
|
|
279
|
+
An `Async::Semaphore(1)` mutex on `send_message` ensures only one command is
|
|
276
280
|
in-flight at a time, so replies are always delivered to the correct caller.
|
|
277
281
|
This also serializes commands issued by event hooks (which run in their own
|
|
278
282
|
fibers) with the main session flow.
|
|
@@ -16,16 +16,19 @@ module Librevox
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def connect
|
|
19
|
-
|
|
20
|
-
stream = IO::Stream(
|
|
19
|
+
socket = TCPSocket.open(@server, @port)
|
|
20
|
+
stream = IO::Stream(socket)
|
|
21
21
|
@connection = Protocol::Connection.new(stream)
|
|
22
|
-
|
|
22
|
+
send_message "auth #{@auth}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def send_message(msg)
|
|
26
|
+
@connection.send_message(msg)
|
|
23
27
|
read_response
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
def command(*args)
|
|
27
|
-
|
|
28
|
-
read_response
|
|
31
|
+
send_message(super(*args))
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
def read_response
|
|
@@ -34,6 +37,13 @@ module Librevox
|
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
40
|
+
def application(uuid, app, args = nil)
|
|
41
|
+
parts = ["sendmsg #{uuid}", "call-command: execute", "execute-app-name: #{app}"]
|
|
42
|
+
parts << "execute-app-arg: #{args}" if args && !args.empty?
|
|
43
|
+
parts << "event-lock: true"
|
|
44
|
+
send_message parts.join("\n")
|
|
45
|
+
end
|
|
46
|
+
|
|
37
47
|
def close
|
|
38
48
|
@connection.close
|
|
39
49
|
end
|
|
@@ -6,7 +6,7 @@ require 'async/semaphore'
|
|
|
6
6
|
module Librevox
|
|
7
7
|
module Listener
|
|
8
8
|
class Base
|
|
9
|
-
def initialize(connection
|
|
9
|
+
def initialize(connection)
|
|
10
10
|
@connection = connection
|
|
11
11
|
@reply_queue = Async::Queue.new
|
|
12
12
|
@command_mutex = Async::Semaphore.new(1)
|
|
@@ -34,7 +34,7 @@ module Librevox
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def command(*args)
|
|
37
|
-
@listener.
|
|
37
|
+
@listener.send_message(super(*args))
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -48,9 +48,9 @@ module Librevox
|
|
|
48
48
|
@command_delegate ||= CommandDelegate.new(self)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def
|
|
51
|
+
def send_message(msg)
|
|
52
52
|
@command_mutex.acquire do
|
|
53
|
-
|
|
53
|
+
@connection.send_message(msg)
|
|
54
54
|
@reply_queue.dequeue
|
|
55
55
|
end
|
|
56
56
|
end
|
|
@@ -81,10 +81,6 @@ module Librevox
|
|
|
81
81
|
def on_event(event)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
def write(data)
|
|
85
|
-
@connection&.write(data)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
84
|
def run_session
|
|
89
85
|
end
|
|
90
86
|
|
|
@@ -24,7 +24,7 @@ module Librevox
|
|
|
24
24
|
barrier.async { client.run }
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def initialize(connection
|
|
27
|
+
def initialize(connection, args = {})
|
|
28
28
|
super(connection)
|
|
29
29
|
@auth = args[:auth] || "ClueCon"
|
|
30
30
|
end
|
|
@@ -32,15 +32,15 @@ module Librevox
|
|
|
32
32
|
def run_session
|
|
33
33
|
Librevox.logger.info "Connected."
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
send_message "auth #{@auth}"
|
|
36
36
|
|
|
37
37
|
events = self.class.subscribe_events || ['ALL']
|
|
38
|
-
|
|
38
|
+
send_message "event plain #{events.join(' ')}"
|
|
39
39
|
|
|
40
40
|
filters = self.class.subscribe_filters || {}
|
|
41
41
|
filters.each do |header, values|
|
|
42
42
|
[*values].each do |value|
|
|
43
|
-
|
|
43
|
+
send_message "filter #{header} #{value}"
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -14,40 +14,33 @@ module Librevox
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def application(app, args = nil, params = {})
|
|
17
|
-
parts = ["call-command: execute", "execute-app-name: #{app}"]
|
|
17
|
+
parts = ["sendmsg", "call-command: execute", "execute-app-name: #{app}"]
|
|
18
18
|
parts << "execute-app-arg: #{args}" if args && !args.empty?
|
|
19
19
|
parts << "event-lock: true"
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
send_message parts.join("\n")
|
|
22
|
+
response = @app_complete_queue.dequeue
|
|
22
23
|
@session = response.content
|
|
23
24
|
|
|
24
25
|
params[:variable] ? variable(params[:variable]) : nil
|
|
25
26
|
end
|
|
26
27
|
|
|
27
|
-
def sendmsg(msg)
|
|
28
|
-
@command_mutex.acquire do
|
|
29
|
-
write "sendmsg\n#{msg}\n\n"
|
|
30
|
-
@reply_queue.dequeue # command/reply ack
|
|
31
|
-
end
|
|
32
|
-
@app_complete_queue.dequeue # CHANNEL_EXECUTE_COMPLETE
|
|
33
|
-
end
|
|
34
|
-
|
|
35
28
|
attr_accessor :session
|
|
36
29
|
|
|
37
30
|
# Called when a new session is initiated.
|
|
38
31
|
def session_initiated
|
|
39
32
|
end
|
|
40
33
|
|
|
41
|
-
def initialize(connection
|
|
34
|
+
def initialize(connection)
|
|
42
35
|
super(connection)
|
|
43
36
|
@session = nil
|
|
44
37
|
@app_complete_queue = Async::Queue.new
|
|
45
38
|
end
|
|
46
39
|
|
|
47
40
|
def run_session
|
|
48
|
-
@session =
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
@session = send_message("connect").headers
|
|
42
|
+
send_message "myevents"
|
|
43
|
+
send_message "linger"
|
|
51
44
|
session_initiated
|
|
52
45
|
sleep # keep session alive for event hooks and child tasks
|
|
53
46
|
end
|
data/lib/librevox/version.rb
CHANGED