title: Freeswitch Event Socket Library
body: <p>I'm trying to use the <a href="https://freeswitch.org/confluence/display/FREESWITCH/Event+Socket+Library" rel="nofollow noreferrer">Event Socket Library (ESL)</a> (<a href="https://web.archive.org/web/20210304203850/https://freeswitch.org/confluence/display/FREESWITCH/Event+Socket+Library" rel="nofollow noreferrer">archive</a>)  from FreeSWITCH but I guess this question is more about the technique and &quot;how to&quot; than anything else.</p>
  <p>The code below is what my question is about and can be found <a href="https://github.com/traviscross/freeswitch/blob/master/libs/esl/managed/ManagedEslTest/Program.cs" rel="nofollow noreferrer">here</a>.</p>
  <pre><code>static void OutboundModeSync(Object stateInfo)
  {
      //...
      while (true)
      {
          Socket sckClient = tcpListener.AcceptSocket();
  
          //Initializes a new instance of ESLconnection, and connects to the host $host on the port $port, and supplies $password to freeswitch
          ESLconnection eslConnection = new ESLconnection(sckClient.Handle.ToInt32());
  
          Console.WriteLine(&quot;Execute(\&quot;answer\&quot;)&quot;);
          eslConnection.Execute(&quot;answer&quot;, String.Empty, String.Empty);
          Console.WriteLine(&quot;Execute(\&quot;playback\&quot;)&quot;);
          eslConnection.Execute(&quot;playback&quot;, &quot;music/8000/suite-espanola-op-47-leyenda.wav&quot;, String.Empty);
          Console.WriteLine(&quot;Execute(\&quot;hangup\&quot;)&quot;);
          eslConnection.Execute(&quot;hangup&quot;, String.Empty, String.Empty);
      }
      //...
  }
  
  static void OutboundModeAsync(Object stateInfo)
  {
      //...
      while (true)
      {
          tcpListener.BeginAcceptSocket((asyncCallback) =&gt;
          {
              TcpListener tcpListened = (TcpListener)asyncCallback.AsyncState;
  
              Socket sckClient = tcpListened.EndAcceptSocket(asyncCallback);
  
              //Initializes a new instance of ESLconnection, and connects to the host $host on the port $port, and supplies $password to freeswitch
              ESLconnection eslConnection = new ESLconnection(sckClient.Handle.ToInt32());
  
              ESLevent eslEvent = eslConnection.GetInfo();
              //...
              while (eslConnection.Connected() == ESL_SUCCESS)
              {
                  eslEvent = eslConnection.RecvEvent();
                  Console.WriteLine(eslEvent.Serialize(String.Empty));
              }
  
              sckClient.Close();
          }, tcpListener);
  
          Thread.Sleep(50);
      }
  }
  </code></pre>
  <p>(I'm using FreeSWITCH ESL in <a href="https://freeswitch.org/confluence/display/FREESWITCH/Event+Socket+Outbound" rel="nofollow noreferrer">outbound mode</a>). As far as I understand, both the &quot;Sync&quot; and &quot;ASync&quot; method are in an infinite loop waiting (<strong>blocking</strong>) for an event, reacting whenever some event is received from FreeSWITCH.</p>
  <p>However, I would like to create a Windows service that tracks all calls FreeSWITCH throws at me. I want another application to call my service, and tell it to send &quot;<code>Foo</code>&quot; to connection &quot;<code>XYZ</code>&quot;. So I'd keep track of a dictionary of connections where the key is the connection-(GU)ID. However, if that connection is waiting (blocking) for an event, I don't see how I could use it to &quot;butt-in&quot; and send my message, regardless if an event is received from FreeSWITCH to &quot;free up&quot; the blocking thread.</p>
  <p>As an aside: by &quot;butting-in&quot; I mean that, if for some reason I, for example, decide I want to hangup a connection (some timer fired for example) I want to be able to send a hangup, regardless wether the connection is waiting for an event to be sent from FreeSWITCH (which could take a long time if nothing happens).</p>
  <p>I could use <a href="https://freeswitch.org/confluence/display/FREESWITCH/Event+Socket+Library#EventSocketLibrary-recvEventTimed" rel="nofollow noreferrer">recvEventTimed</a> to create a &quot;polling mechanism&quot; but this approach has three problems:</p>
  <ol>
  <li>polling feels dirty</li>
  <li>whenever I want to &quot;butt-in&quot;, I want my message sent ASAP, not 50ms (or 1ms) later</li>
  <li><code>recvEventTimed</code> seems to ignore anything below ~500ms going so it'll poll like crazy. And 500ms is too much latency for me.</li>
  </ol>
  <p>Aside from these (I could file a bug report), polling doesn't feel right.</p>
  <p>I would like to &quot;accept a connection&quot;, tell the ESL to wait (blocking) for an event and then raise an event so I could use an <strong>event-based approach</strong>. I expect to handle lots of connections so I would prefer low latencies, no (or little) polling and a clean approach to handle all these connections, while they last, giving me free &quot;two way, unpolled, event-based&quot; communication.</p>
  <p>I have considered RX (Reactive extensions) and implementing my own &quot;ESL&quot; with .Net Async sockets (as opposed to the FreeSWITCH provided binary) and other approaches. But I can't seem to find a way to neatly implement my wishes/requirements without lots of boilerplate or/and nasty threading stuff etc. I'm pretty sure I should be able to use <code>async</code>/<code>await</code> but get lost on how to do that exactly. Any help would be very much appreciated.</p>
  <p>Simple description:</p>
  <pre><code>* Connection comes in
  * Accept connection + get GUID from connection
  * Put connection in some collection for later reference
  * Bind delegate to connection (`EventReceived` event)
  * Use collection to get connection and send a message (preferrably async (&quot;fire and forget&quot;), but blocking COULD be acceptable as long as it only blocks that specific connection) to &quot;butt-in&quot; whenever I want to
  </code></pre>
  <p>The collection will be hosted in a Windows Service which I can contact to for I/O to my FreeSWITCH connections / list available connections etc.</p>
  <p>So, I imagine something, like, in &quot;pseudo code&quot;:</p>
  <pre><code>MyService {
      stopped = false;
  
      void OnStart {
          while (!stopped) {
            var someconn = esl.waitforconnection();
            var id = someconn.getCallId();
            someconn.EventReceived += MyDelegate(...);
            mydict.add(id, someconn);
          }
      }
  
      void OnStop {
        stopped = true;
      }
  
      void ButtIn(string callid, string msg) {
          mydict[callid].send(msg);
      }
  
      void MyDelegate(EventData evtdata) {
          //Do something with evtdata if desired
      }
  }
  </code></pre>
  <p>How would I go about implementing this given the ESL provided by FreeSwitch is not event-based and has only a blocking &quot;wait for event&quot; or a polling &quot;wait <em>X</em> ms for event&quot;?</p>
  <p><strong>tl;dr</strong>: Don't want infinite-while-loops / polling but more of an event-based approach, preferrably using <code>async</code>/<code>await</code>, clean + simple code to use once the 'underlying &quot;ESL connection&quot;' is wrapped/abstracted in my own class(es). Need help/advice in best approach. No threading/sockets-guru.</p>