[Freeswitch-users] Asynchronous communication with FreeSWITCH's mod_event_socket
Richard Open Source
oss.richard at gmail.com
Fri Sep 19 06:35:51 PDT 2008
I agree.
I have started working on a library like asterisk-java (now onhold but
hopefully can continue working on it in a couple of weeks) using groovy
(will name it fs-groovy :))
The way I check if the command was successful is to look for the Event with
CHANNEL_EXECUTE_COMPLETE and Application and ApplicationData.
Here is how I implemented it. Still needs more work though.
--
2<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L2>
3<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L3>
import
org.apache.mina.common.IoSession
4<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L4>
import
java.util.concurrent.BlockingQueue
5<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L5>
import
java.util.concurrent.Executors
6<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L6>
import
java.util.concurrent.ExecutorService
7<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L7>
import
java.util.concurrent.Future
8<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L8>
import
java.util.concurrent.Callable
9<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L9>
import
java.util.concurrent.ExecutionException
10<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L10>
import
java.util.concurrent.TimeoutException
11<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L11>
import
java.util.concurrent.TimeUnit
12<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L12>
13<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L13>
14<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L14>
15<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L15>
class
Session { 16<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L16>
private IoSession session
17<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L17>
private FSEventHandler handler
18<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L18>
private BlockingQueue<String> msgQ
19<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L19>
private final ExecutorService executor =
Executors.newSingleThreadExecutor()
20<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L20>
private final static long DEFAULT_TIMEOUT = 5000
21<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L21>
22<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L22>
def data 23<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L23>
24<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L24>
def Session(IoSession s, BlockingQueue q) {
25<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L25>
session = s
26<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L26>
msgQ = q
27<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L27>
} 28<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L28>
29<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L29>
private def executeAndWait(Closure task, long timeout=0) {
30<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L30>
Future <CommandResult> f = executor.submit(task as Callable)
31<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L31>
def result
32<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L32>
def boolean success = false
33<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L33>
try {
34<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L34>
if (timeout != 0) {
35<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L35>
result = f.get(timeout, TimeUnit.MILLISECONDS)
36<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L36>
} else {
37<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L37>
result = f.get()
38<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L38>
}
39<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L39>
if (result.code == CommandResult.OK) data =
result.data 40<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L40>
} catch (ExecutionException e) {
41<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L41>
// Should log here
42<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L42>
} catch (TimeoutException e) {
43<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L43>
f.cancel(true)
44<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L44>
}
45<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L45>
46<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L46>
return result
47<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L47>
} 48<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L48>
49<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L49>
def answer() {
50<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L50>
def task = {
51<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L51>
def done = false
52<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L52>
def r = new CommandResult()
53<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L53>
sendMessage("answer")
54<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L54>
while (! done) {
55<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L55>
def m = msgQ.take()
56<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L56>
if ((m?.event?.Name ==
"CHANNEL_EXECUTE_COMPLETE") && (m?.Application == "answer")) {
57<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L57>
done = true
58<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L58>
r.code = CommandResult.OK
59<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L59>
r.data = m
60<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L60>
}
61<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L61>
}
62<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L62>
return r
63<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L63>
}
64<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L64>
executeAndWait(task, DEFAULT_TIMEOUT)
65<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L65>
} 66<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L66>
67<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L67>
def unset(var) {
68<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L68>
def task = {
69<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L69>
def done = false
70<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L70>
def r = new CommandResult()
71<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L71>
sendMessage("unset", var)
72<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L72>
while (! done) {
73<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L73>
def m = msgQ.take()
74<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L74>
if ((m?.event?.Name ==
"CHANNEL_EXECUTE_COMPLETE")
75<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L75>
&& (m?.Application ==
"unset") 76<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L76>
&& (m?.ApplicationData
== var)) { 77<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L77>
done = true
78<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L78>
r.code =
CommandResult.OK
79<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L79>
r.data = m
80<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L80>
}
81<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L81>
}
82<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L82>
return r
83<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L83>
}
84<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L84>
executeAndWait(task, DEFAULT_TIMEOUT)
85<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L85>
} 86<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L86>
87<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L87>
def queueDtmf(dtmfs) {
88<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L88>
def task = {
89<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L89>
def done = false
90<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L90>
def r = new CommandResult()
91<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L91>
sendMessage("queue_dtmf", dtmfs)
92<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L92>
while (! done) {
93<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L93>
def m = msgQ.take()
94<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L94>
if ((m?.event?.Name ==
"CHANNEL_EXECUTE_COMPLETE")
95<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L95>
&& (m?.Application ==
"queue_dtmf") 96<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L96>
&& (m?.ApplicationData
== dtmfs)) { 97<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L97>
done = true
98<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L98>
r.code =
CommandResult.OK
99<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L99>
r.data = m
100<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L100>
}
101<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L101>
}
102<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L102>
return r
103<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L103>
}
104<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L104>
executeAndWait(task, DEFAULT_TIMEOUT)
105<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L105>
} 106<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L106>
107<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L107>
/* 108<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L108>
def hangup() {
109<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L109>
def task = {
110<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L110>
def done = false
111<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L111>
def r = new CommandResult()
112<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L112>
sendMessage("hangup")
113<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L113>
while (! done) {
114<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L114>
def m = msgQ.take()
115<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L115>
if ((m?.event?.Name ==
"CHANNEL_EXECUTE_COMPLETE")
116<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L116>
&& (m?.Application ==
"queue_dtmf") 117<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L117>
&& (m?.ApplicationData
== dtmfs)) { 118<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L118>
done = true
119<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L119>
r.code =
CommandResult.OK
120<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L120>
r.data = m
121<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L121>
}
122<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L122>
}
123<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L123>
return r
124<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L124>
}
125<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L125>
executeAndWait(task, DEFAULT_TIMEOUT)
126<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L126>
} 127<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L127>
*/
128<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L128>
129<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L129>
def setVariable(String var, String value) {
130<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L130>
def task = {
131<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L131>
def done = false
132<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L132>
def r = new CommandResult()
133<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L133>
sendMessage("set", "${var}=${value}")
134<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L134>
while (! done) {
135<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L135>
def m = msgQ.take()
136<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L136>
if ((m?.event?.Name ==
"CHANNEL_EXECUTE_COMPLETE")
137<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L137>
&& (m?.Application ==
"set") 138<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L138>
&& (m?.ApplicationData
== "${var}=${value}")) {
139<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L139>
done = true
140<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L140>
r.code =
CommandResult.OK
141<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L141>
r.data = m
142<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L142>
}
143<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L143>
}
144<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L144>
return r
145<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L145>
}
146<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L146>
executeAndWait(task, DEFAULT_TIMEOUT)
147<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L147>
148<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L148>
} 149<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L149>
150<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L150>
def export(String var) {
151<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L151>
set("export_vars", var)
152<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L152>
} 153<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L153>
154<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L154>
def bridge(String number) {
155<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L155>
def task = {
156<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L156>
def done = false
157<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L157>
def r = new CommandResult()
158<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L158>
sendMessage("bridge", number)
159<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L159>
while (! done) {
160<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L160>
def m = msgQ.take()
161<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L161>
//
println m
162<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L162>
if (((m?.event?.Name ==
"CHANNEL_EXECUTE_COMPLETE")
163<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L163>
&& (m?.Application ==
"bridge") 164<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L164>
&& (m?.ApplicationData
== number)) || 165<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L165>
((m?.event?.Name ==
"CHANNEL_UNBRIDGE")
166<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L166>
&&
(m?.variable.bridge_channel == number)) || (m?.SESSIONCLOSED == "true")) {
167<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L167>
done = true
168<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L168>
r.code =
CommandResult.OK
169<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L169>
r.data = m
170<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L170>
}
171<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L171>
}
172<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L172>
return r
173<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L173>
}
174<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L174>
executeAndWait(task)
175<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L175>
} 176<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L176>
177<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L177>
def promptForDigits(int min, int max, String soundFile, String
variableName, long timeout, String terminator) {
178<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L178>
def task = {
179<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L179>
def done = false
180<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L180>
def r = new CommandResult()
181<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L181>
def appData = "${min} ${max} ${soundFile}
${variableName} ${timeout} ${terminator}"
182<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L182>
sendMessage("read", appData, true)
183<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L183>
while (! done) {
184<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L184>
def m = msgQ.take()
185<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L185>
if ((m?.event?.Name ==
"CHANNEL_EXECUTE_COMPLETE")
186<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L186>
&& (m?.Application ==
"read") 187<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L187>
&& (m?.ApplicationData
== appData)) { 188<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L188>
done = true
189<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L189>
r.code =
CommandResult.OK
190<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L190>
r.data = m
191<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L191>
}
192<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L192>
}
193<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L193>
return r
194<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L194>
}
195<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L195>
executeAndWait(task, timeout)
196<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L196>
} 197<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L197>
198<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L198>
def originate(String url) {
199<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L199>
sendMessage("originate", url, true)
200<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L200>
} 201<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L201>
202<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L202>
def sleep(int sec) {
203<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L203>
sendMessage("sleep", new Integer(sec*1000).toString())
204<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L204>
} 205<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L205>
206<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L206>
def say(String phrase) {
207<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L207>
sendMessage("phrase", "spell,$phrase")
208<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L208>
} 209<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L209>
210<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L210>
def script() {
211<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L211>
return "jeprox"
212<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L212>
} 213<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L213>
214<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L214>
private def sendMessage(String app, String arg=null, boolean
event_lock=false) {
215<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L215>
String msg = "sendmsg\ncall-command:
execute\nexecute-app-name: ${app}"
216<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L216>
if (arg) {
217<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L217>
msg += "\nexecute-app-arg: ${arg}"
218<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L218>
}
219<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L219>
if (event_lock) {
220<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L220>
msg += "\nevent-lock: ${event_lock}"
221<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L221>
}
222<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L222>
System.out.println(msg)
223<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L223>
session.write("$msg\n\n")
224<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L224>
} 225<http://trac.protus.org/trac/browser/myfreeswitch/src/groovy/org/protus/freeswitch/Session.groovy?rev=241#L225>
}
On Thu, Sep 18, 2008 at 5:49 PM, Luke Graybill <killarny at gmail.com> wrote:
> I've been doing a lot of work recently with FreeSWITCH's mod_event_socket,
> and I wanted to comment a bit about the syntax used for commands through the
> socket while using asynchronous mode. I haven't tried the synchronous mode
> yet, as I always want to be free to be able to execute commands without
> waiting for other commands to finish. For instance, I need to be able to
> collect DTMF events while I'm playing a sound file, so that the user can do
> things like select menu items without listening to the entire menu first.
>
> Asterisk's AMI protocol allows you to specify an ActionID along with every
> command that you send. Asterisk then includes this ActionID with every event
> that is related to that command, making it cake to coordinate an
> asynchronous client.
>
> However, even in async mode, FreeSWITCH's mod_event_socket doesn't
> communicate any identifying information for command responses, or for events
> triggered by a previous command, unless one uses the bgapi command set. This
> command set is not applicable to every situation, though. It only applies to
> commands which manipulate the call; if one needs to manipulate the channel,
> then messages must be used through the sendmsg command set, which doesn't
> provide any specific identifying information.
>
> Now, to complicate things, with all commands (even bgapi) the protocol
> works something like this: you send a command, and wait for a response from
> mod_event_socket. This response is assumed to be immediate before anything
> else the client might receive from mod_event_socket, and in the case of
> bgapi, this response will contain a job-id to use for comparing job-related
> events later.
>
> For example, for the following command:
>
> sendmsg
> call-command: execute
> execute-app-name: answer\n\n
>
> The response is this:
>
> Content-Type: command/reply
> Reply-Text: +OK
>
> That response is generic to nearly every single command sent, and is only
> really saying "The last transmission was a valid command, and didn't
> immediately fail". The command may actually fail later, and command specific
> feedback is generally contained in later events (which have no unique
> identifying information).
>
> My issue here is that this seems to be forcing an asynchronous client to
> rely upon a synchronous ordering of response directly following command,
> thus violating the very concepts of an asynchronous protocol in which there
> should be no assumed order. Not only that, but this method increases the
> complexity of a client, which must be aware of limitations that wouldn't
> ordinarily be required by a true asynchronous protocol. An asynchronous
> client should be unconcerned with listening for a synchronous response to
> every command.
>
> My suggested solution is to apply the job-id concept from bgapi to messages
> as well, and to go a step further; borrow the Asterisk idea of transmitting
> an identifier along with each command. Every response and event related to
> that command should then contain the very same identifier in the header.
>
> _______________________________________________
> Freeswitch-users mailing list
> Freeswitch-users at lists.freeswitch.org
> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
> http://www.freeswitch.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freeswitch.org/pipermail/freeswitch-users/attachments/20080919/cd821a4d/attachment-0002.html
More information about the FreeSWITCH-users
mailing list