[Freeswitch-users] Asynchronous communication with FreeSWITCH's mod_event_socket

Richard Open Source oss.richard at gmail.com
Fri Sep 19 09:35:51 EDT 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-0001.html 


More information about the Freeswitch-users mailing list