Comments (13)
That's actually not a bad idea. When we built the first version, the idea was to push something into the open rapidly, so that people can start building stuff. If you have a working patch, please generate a pull request and I'll examine how to integrate it in.
from phpari.
Technically speaking, the easiest would be to do something like this:
public function applications_list()
{
try {
if (is_null($this->pestObject))
throw new Exception("PEST Object not provided or is null", 503);
$uri = "/applications";
$result = $this->pestObject->get($uri);
return $result;
} catch (Exception $e) {
die("Exception raised: " . $e->getMessage() . "\nFile: " . $e->getFile() . "\nLine: " . $e->getLine());
}
}
In this methodology, your script will simply blow up in your face, spitting out the error message right in your face. Personally, I hate when scripts terminate like that, it gives me bad memories from the nights I used to code too much JAVA.
However, I think that probably holding a last_error public variable could come in handy, something that would hold the last error message, which can be retrieved in a case where the last request failed.
What do you think?
from phpari.
I've created a new branch called "enhanced-exception-handling". Basically, I've added a public variable to "asterisk" and "applications" module, that will hold the last Exception that was raised within a method.
The concept is simple - if you got a FALSE result, simply check the contents of $last_error in order to get your Exception object.
For example:
$conn = new phpari(ARI_USERNAME, ARI_PASSWORD, "hello-world", ARI_SERVER, ARI_PORT, ARI_ENDPOINT); //create new object
$app = new applications($conn);
header('Content-Type: application/json');
$applist = $app->applications_list();
if (!$applist)
vardump($app->last_error)
else
echo json_encode($applist);
Again, just a concept.
from phpari.
The response to a connection failure should be the same as the underlying ReactPHP library.
If I use their http-client example and have it request from an invalid URL, the $request->on('end', function()) is passed a string describing the exception ' exception 'React\SocketClient\ConnectionException' with message 'Connection refused' in (...)/Connector.php:74' complete with a stack trace.
This is ostensibly to allow the event loop to continue running, while still being able to report full debug information via whatever method it chooses.
This library should do something similar -- allow you to specify a callback function along the same lines of request->on(event,func()) that provides error handling.
The library itself should however never execute exit() or die(), since it takes away the user's ability to handle errors themselves, and makes presumptions about the error output format (i.e. should it be text, or html, or ??).
As I continue working with this I will have some further suggestions.
from phpari.
Hey Scott,
Previously, you've remarked regarding the PEST library - but hadn't responded to my query.
Nir
from phpari.
I'm still working through how best to formulate a stasis app event loop. Ideally that would use the React event loop, possibly at the cost of requireing some other changes. Once I've figured that out I'll get back to you with a solid recommendation.
from phpari.
Tried replicating the issue you've indicated, regarding not having StasisStart work - here is a sample I've made that shows that it is being accepted:
class BasicAriConnector
{
public function __construct()
{
$phpariObject = new phpari(ARI_USERNAME, ARI_PASSWORD, "hello-world", ARI_SERVER, ARI_PORT, ARI_ENDPOINT);
$this->ariEndpoint = $phpariObject->ariEndpoint;
$this->stasisClient = $phpariObject->stasisClient;
$this->stasisLoop = $phpariObject->stasisLoop;
$this->stasisLogger = $phpariObject->stasisLogger;
}
public function handlers()
{
try {
$this->stasisClient->on("request", function ($headers) {
$this->stasisLogger->notice("Request received!");
});
$this->stasisClient->on("handshake", function () {
$this->stasisLogger->notice("Handshake received!");
});
$this->stasisClient->on("message", function ($message) {
$messageObject = json_decode($message->getData());
echo $messageObject->type . " Received \n";
});
} catch (Exception $e) {
echo $e->getMessage();
exit(99);
}
}
public function execute()
{
try {
$this->stasisClient->open();
$this->stasisLoop->run();
} catch (Exception $e) {
echo $e->getMessage();
exit(99);
}
}
}
$basicAriClient = new BasicAriConnector();
/**
* Get some basic information from ARI
*/
$basicAriClient->handlers();
$basicAriClient->execute();
exit(0);
The output looks like this:
$ php BasicAriConnector.php
2014-10-05T21:17:31+02:00 NOTICE (5): Request received!
2014-10-05T21:17:31+02:00 NOTICE (5): Handshake received!
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
I've used a simple dialplan that activates Stasis and the program it self is very straight forward.
It is using the React event loop, phpari simply hides most of it from the developer - making it a fairly straight forward task.
from phpari.
If you're running Asterisk on the same machine as PHP, you likely won't see
the issue manifest. It's a race condition which may not appear always in
different network conditions.
The Asterisk system I'm testing against is on a cloud (vps) server. I can
get you an account to play with on that box if you wanted to. Once I
applied the fix I wrote up the issue disappears. It's a flaw in the
handshake validation of the phpws library.
I'm working on a two examples - one a simple answer, playback, hangup, and
another with a more complicated stasis app with some interactive components.
I have some recommendations on how to improve the phpari library, which I
will share with you in detail later. The first is simply to consider that
there are two types of usage for the library - a rest client only model
where a few requests are made and that's it, and a stasis app with event
loop model where the app registers as a stasis app with a specific name (or
multiple apps with separate names), hangs around for a long time on the
event loop, and issues rest calls back to initiate actions as a reaction to
those events. The former does not need the react event loop, websocket
connection, or stasis app name in the constructor. But it should be
possible to have multiple stasis apps with separate names operating under a
single react event loop. My recommendation to achieve this is to break out
the stasis app functions as a separate class instance, say $app =
$phpari->stasisApp('app_name', $loop);.
Hiding the react loop as a default stasisApp('nameonly') is a good idea,
but one of the design constraints of an cooperative tasking event loop is
that you can only have one. Thus they recommend that libraries allow an
externally instantiated event loop to be passed in.
_------------------------------ Scott Griepentrog +1-_317-644-2228
Software Telephony Group http://stg.net/
{
"fullName" : "Scott Griepentrog",
"email" : "[email protected]",
"phone" : "tel:+13176442228",
"sip" : "sip:[email protected]",
"company" : "Software Telephony Group",
"website" : "http://stg.net",
"twitter" : "@stgnet",
"google+" : "http://google.com/+scottgriepentrog",
"linkedIn" : "http://linkedin.com/in/stgnet",
"tags" : ["software development","asterisk","telecom","voip"]
}
On Sun, Oct 5, 2014 at 2:21 PM, Nir Simionovich [email protected]
wrote:
Tried replicating the issue you've indicated, regarding not having
StasisStart work - here is a sample I've made that shows that it is being
accepted:class BasicAriConnector { public function __construct() { $phpariObject = new phpari(ARI_USERNAME, ARI_PASSWORD, "hello-world", ARI_SERVER, ARI_PORT, ARI_ENDPOINT); $this->ariEndpoint = $phpariObject->ariEndpoint; $this->stasisClient = $phpariObject->stasisClient; $this->stasisLoop = $phpariObject->stasisLoop; $this->stasisLogger = $phpariObject->stasisLogger; } public function handlers() { try { $this->stasisClient->on("request", function ($headers) { $this->stasisLogger->notice("Request received!"); }); $this->stasisClient->on("handshake", function () { $this->stasisLogger->notice("Handshake received!"); }); $this->stasisClient->on("message", function ($message) { $messageObject = json_decode($message->getData()); echo $messageObject->type . " Received \n"; }); } catch (Exception $e) { echo $e->getMessage(); exit(99); } } public function execute() { try { $this->stasisClient->open(); $this->stasisLoop->run(); } catch (Exception $e) { echo $e->getMessage(); exit(99); } } } $basicAriClient = new BasicAriConnector(); /** * Get some basic information from ARI */ $basicAriClient->handlers(); $basicAriClient->execute(); exit(0);
The output looks like this:
$ php BasicAriConnector.php
2014-10-05T21:17:31+02:00 NOTICE (5): Request received!
2014-10-05T21:17:31+02:00 NOTICE (5): Handshake received!StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
StasisStart Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd Received
ChannelHangupRequest Received
StasisEnd ReceivedI've used a simple dialplan that activates Stasis and the program it self
is very straight forward.It is using the React event loop, phpari simply hides most of it from the
developer - making it a fairly straight forward task.—
Reply to this email directly or view it on GitHub
#17 (comment)
.
from phpari.
Actually, I'm running my Asterisk server on a cloud server at DigitalOcean - and the Stasis app is running from my Home machine - a few thousands miles away :-)
I see your point regarding the stasis app. Technically speaking, you really don't need the React in order to initiate the PEST objects, that is correct.
I'm waiting to see your recommendations regarding react :-)
from phpari.
So, either a fluke that I found that, or possibly because I'm running trunk
(as in asterisk 14). Would have tripped somebody up at some point to be
sure.
I'm going to get my app completely coded and functional before I start
sending you specifics so that it's based on proven working code.
_------------------------------ Scott Griepentrog +1-_317-644-2228
Software Telephony Group http://stg.net/
{
"fullName" : "Scott Griepentrog",
"email" : "[email protected]",
"phone" : "tel:+13176442228",
"sip" : "sip:[email protected]",
"company" : "Software Telephony Group",
"website" : "http://stg.net",
"twitter" : "@stgnet",
"google+" : "http://google.com/+scottgriepentrog",
"linkedIn" : "http://linkedin.com/in/stgnet",
"tags" : ["software development","asterisk","telecom","voip"]
}
On Sun, Oct 5, 2014 at 4:05 PM, Nir Simionovich [email protected]
wrote:
Actually, I'm running my Asterisk server on a cloud server at DigitalOcean
- and the Stasis app is running from my Home machine - a few thousands
miles away :-)I see your point regarding the stasis app. Technically speaking, you
really don't need the React in order to initiate the PEST objects, that is
correct.I'm waiting to see your recommendations regarding react :-)
—
Reply to this email directly or view it on GitHub
#17 (comment)
.
from phpari.
Well,
Looks like I just experienced the same thing you've described. It seems a little transient or something, as I can't always re-produce it.
I've devised a very nice Stasis application example.
from phpari.
- Added error handling using "lasterror" and "lasttrace" variables in the phpari object, you can use that for error checking.
- Modified the phpari class to enable proper buildup of PHP events callback - see BasicStasisApplication.php file for additional information.
from phpari.
This is now being handled properly and had been regressed.
Thanks for the heads up @stgnet
from phpari.
Related Issues (20)
- Is this project dead HOT 4
- Problems answering the channel HOT 13
- Connection refused HOT 2
- Statis App not receiving events HOT 6
- Migration to guzzle incomplete? HOT 2
- basic example not working HOT 1
- Cannot redirect or continue channel HOT 7
- Undefined property: phpari::$ariEndpoint HOT 2
- Discussion/Overhaul: Non Blocking Async Request HOT 4
- 183 Session Progress HOT 2
- Connecting 2 incoming channels HOT 3
- Testing StasisAppDial.php HOT 4
- Guzzle issues on php 7.1 HOT 3
- Error Connect Asterisk HOT 6
- CALLERID(name) does not work, HOT 6
- socket error when i stoping aplication HOT 1
- BUG: In loading ini File HOT 1
- Ringing timeout 30 seconds HOT 1
- Read any keypress using asterisk HOT 3
- Passing options to dial HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from phpari.