phpinnacle / ridge Goto Github PK
View Code? Open in Web Editor NEWPure asynchronous PHP implementation of the AMQP 0-9-1 protocol.
License: MIT License
Pure asynchronous PHP implementation of the AMQP 0-9-1 protocol.
License: MIT License
if PHPinnacle\Ridge\Client
receive PHPinnacle\Ridge\Protocol\ConnectionCloseFrame
it will never chnage state to STATE_NOT_CONNECTED
. There is no way to detect/subscribe on canceled connection from user code.
Maybe neccesary to change state here?
Line 130 in b362ee6
If some reason clent not able to send heartbeats (broken network etc) RabbitMQ server will close connection automaticly on his own side, but consumer still connected to server. Clinet is waiting of new messages but they will never come, because rabbitmq dosn`t have connection (and consumer) any more .
There is code in PHPinnacle\Ridge\Connection for send heartbeats, but no code for receive it and broke connection if heartbeats didn't came at proper time.
Mybe good idea to pass callback to heartbeat init function and call it if last read was too later.
Line 163 in b362ee6
public function heartbeat(int $interval, ?callable $connectionLost = null): void
amphp 3 is stable and was released more than 1 year ago. Are there any plans to support this version with the next major update?
I try subscribe to channel with:
yield $channel->consume('onMessage', 'queue', 'tag');
yield $channel->consume('onMessage', 'queue', 'tag');
For first request it working, but for the second it remains pending for a long time.
In rabbitmq I see:
operation basic.consume caused a connection exception not_allowed: "attempt to reuse consumer tag 'tag'"
This also applies to the queueDeclare method with different parameters.
I think need to throw an exception when the server raises an error.
When we pass an invalid vhost, the broker sends a ConnectionCloseFrame and terminates the connection, but Ridge does not capture this frame and does not throw an exception.
Example:
use Amp\Loop;
use PHPinnacle\Ridge\Client;
Loop::run(function () {
$client = Client::create('amqp://guest:guest@localhost:5672/unknown-vhost');
yield $client->connect();
echo "Execution will never get here. Nor will an exception be thrown.";
// (...)
});
asyncCall(function () {
yield $this->await(Protocol\ConnectionCloseFrame::class);
// (...)
});
should be in front of:
Lines 122 to 124 in adcced8
replyCode
is 530
(decimal) and replyText
"NOT_ALLOWED - vhost unknown-vhost not found"
.
Additionally, the status change to STATE_DISCONNECTING
and STATE_NOT_CONNECTED
is missing in the code below.
Lines 126 to 141 in adcced8
Version 1.3.0
Simple code:
\Amp\Loop::run(function() {
$client = Client::create("amqp://guest:guest@localhost:5672/?timeout=5000");
yield $client->connect();
print_r('Connected: ' . $client->isConnected() . PHP_EOL);
\Amp\Loop::repeat(1000, fn() => print_r('Connected: ' . $client->isConnected() . PHP_EOL));
});
And see in log:
Connected: 1
Connected: 1
Connected:
Connected:
Connected:
Bunny is based on ReactPHP, however since Amphp does support React promises, bunny should be able to work with Amphp. What are the reasons for this library then? You mentioned "some strange bugs" but that's way too abstract. What are those bugs? Are there any other advantages and/or differences from bunny?
Fatal error received after missed heartbeats
rabbitmq | missed heartbeats from client, timeout: 60s
backend | Fatal error (Uncaught ErrorException)
Notice: Undefined property: PHPinnacle\Ridge\Connection::$socket
in /var/www/vendor/phpinnacle/ridge/src/Connection.php:200
Docker images based on php:7.2-cli-alpine and rabbitmq:3.7.2-management-alpine
When we provide an incorrect login or password, the broker closes the connection (without sending the ConnectionCloseFrame, it just terminates the socket connection) and Ridge does not inform about it in any way. I think an exception should be thrown informing about this fact.
Example:
use Amp\Loop;
use PHPinnacle\Ridge\Client;
Loop::run(function () {
$client = Client::create('amqp://user:wrongpass@localhost:5672');
yield $client->connect();
echo "Execution will never get here. Nor will an exception be thrown.";
// (...)
});
RabbitMQ logs:
2020-09-10 08:39:02.330 [info] <0.13118.7> accepting AMQP connection <0.13118.7> (192.168.5.23:33952 -> 172.17.0.3:5672)
2020-09-10 08:39:02.332 [error] <0.13118.7> Error on AMQP connection <0.13118.7> (192.168.5.23:33952 -> 172.17.0.3:5672, state: starting):
AMQPLAIN login refused: user 'user' - invalid credentials
2020-09-10 08:39:05.332 [info] <0.13118.7> closing AMQP connection <0.13118.7> (192.168.5.23:33952 -> 172.17.0.3:5672)
Any plans to support PHP 8?
When connecting to RMQ fails ConnectionCloseFrame
is handled but no exception in case of error is thrown.
amqp://test:test@localhost:5672/test
object(PHPinnacle\Ridge\Protocol\ConnectionCloseFrame)#866 (10) {
["replyCode"]=>
int(530)
["replyText"]=>
string(81) "NOT_ALLOWED - access to vhost '/test' refused for user 'test'"
["closeClassId"]=>
int(10)
["closeMethodId"]=>
int(40)
["classId"]=>
int(10)
["methodId"]=>
int(50)
["type"]=>
int(1)
["channel"]=>
int(0)
["size"]=>
int(92)
["payload"]=>
NULL
}
The change is important for all users using non-default vhost
.
Possible fix should add \trim($url['path'], '/')
in Config::parse
Version 1.3.0 with fixed PR #33
Example code:
\Amp\Loop::run(function() {
$client = Client::create("amqp://guest:guest@localhost:5672/?timeout=5000&heartbeat=2000");
yield $client->connect();
print_r('Connected: ' . $client->isConnected() . PHP_EOL);
\Amp\Loop::repeat(1000, fn() => print_r('Connected: ' . $client->isConnected() . PHP_EOL));
});
I add debug lines before write, before check condition and add log in close method
Lines 179 to 195 in 0f86217
print_r('write' . PHP_EOL);
yield $this->write((new Buffer)
...
print_r('check' . PHP_EOL);
if (
Run script and see in log:
Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1
Checking heartbeat correctly. But I simulate RabbitMQ server down with command brew services restart rabbitmq
I see in log:
Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1
write
check
Connected: 1
Connected: 1
close
Connected: 1
Connected: 1
Connected: 1
Connected: 1
Connected: 1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.