friends-of-freeswitch / switchio

asyncio powered FreeSWITCH cluster control
http://switchio.rtfd.io
Mozilla Public License 2.0
191 stars 28 forks source link

How to originate calls from service #61

Open enp opened 5 years ago

enp commented 5 years ago

Hi, Is it possible to originate call from my application (I mean my class with @app and @event_callback)? Maybe anybody can show me simple service based on https://switchio.readthedocs.io/en/latest/services.html which can originate calls in addition to receiving incomimg calls?

goodboy commented 5 years ago

Hey @enp.

Hmm I haven't really done this before (it's usually the opposite - originate a call and then use an app to process it). One thing to start with is the quickstart which shows how to manually originate new calls.

It's actually a bit of an odd use case since apps are Session oriented while an originate cmd spawns a new (set of) session(s), but I guess you could try a few things:

Note this is all a bit tricky with a Service since it's meant to manage a FS process cluster; knowing which FS process should originate the call is potentially involved to figure out. This is exactly why switchio has its own built in autodialer for this kind of thing.

Another thing to note is that the @event_callback api is the legacy callback system. You can now use @switchio.coroutine to decorate async functions. Unfortunately this hasn't been documented yet (as well as many other nice things) as per #33...

Anyway hope this helps.

enp commented 5 years ago

Thanks for you response, but I see @event_callback (and maybe @app) is outdated, right?

Anyway I need for a bit different. I need for some service with two entry point:

So, I need for some mix of https://aiohttp.readthedocs.io/en/stable/web_quickstart.html#run-a-simple-web-server and https://github.com/friends-of-freeswitch/switchio#use-the-power-of-async-and-await with one event loop for two entry points instead of web.run_app(app) and service.run()

What is the best way to do it?

goodboy commented 5 years ago

Hey @enp. Ahh I see you want to create some kind of web service controlled FS service?

I personally don't have any experience integrating these two frameworks but I'd imagine it'd require somehow getting either both event loops to run alongside each other or you'd have to figure out how to get one even loop to run coroutines from both frameworks.

The event loop management in switchio is executed in background thread so you should in theory be able to start both a switchio service and an aiohttop app in one process.

enp commented 5 years ago

Suppose I already have simple web service with explicit event loop. I need to define switchio EventLoop and Connection both in some CallServer class, right? How to define FS event handlers in this case?

goodboy commented 5 years ago

To start the Service running in a background thread you could simply start the underlying clients but without waiting on them as is done in Service.run().

Actually, Service.run(block=False) should work.

@enp if you get this working some docs on how to do it would be greatly appreciated :+1:

goodboy commented 5 years ago

Hmm I guess it would be interesting to see what happens if you tried to use one loop for both. I know we can pass in a loop to the EventLoop but I don't think we have any tests really for that.

Yeah, we'd have to toy around with allowing passing in an event loop to switchio.api.get_client() and then also allowing for not running the event loop in a background thread. That's a bit of work and testing though.

enp commented 5 years ago

So, it is impossible to use one event loop for both now?

Btw, I tried just to import EventListener or EventLoop but I got error:

Traceback (most recent call last):
  File "examples/freeswitch/call.py", line 6, in <module>
    from switchio import Client, EventListener, EventLoop
ImportError: cannot import name 'EventListener'

Why I can't do this?

goodboy commented 5 years ago

So, it is impossible to use one event loop for both now?

No, it just might not work reliably and it's never been tested.

Why I can't do this?

Because EventListener isn't exposed at the top level package. I'd recommend reading the source code before just blindly importing names.

If you are having problems unrelated to this original issue please instead join our riot chat.

goodboy commented 5 years ago

@enp ahh I just realized,

Why I can't do this?

Yeah so the internals tutorial is obviously out of date.

Like I said docs are in a shambles since the port to asyncio.. see #33 as well.

I made an issue #62.

goodboy commented 5 years ago

@enp did you have any luck getting this working?

enp commented 5 years ago

I've used low-level connection in this way because did not found how to pass event loop into get_client or into get_listener

goodboy commented 5 years ago

@enp oh nice. Glad to see the low level stuff is at least useful :+1:

If you're interested in exposing what you need in some of the higher level APIs we'll gladly take PRs for it!

I know that getting this all working with a single loop / thread is definitely possible I just haven't played with it.

I've created #66 to track.

enp commented 5 years ago

Sure, it will be interesting for me to see higher level example with switchio-specific decorators for event processing and aiohttp-specific decorators for http requests/responses both instead of working with loops manually :)