我試圖在我的項目中使用Server Side Events機制。 (這類似於類固醇上的長輪詢)Apache進程不會在與RabbitMQ斷開連接後死亡
來自「Sending events from the server」字幕的例子效果非常好。幾秒鐘後,斷開連接,apache進程終止。此方法工作正常。
但是!如果我嘗試使用RabbitMQ,則在瀏覽器從服務器斷開連接後,Apache不會導致進程中斷(es.close()
)。並且進程保持原樣並在docker容器重新啓動後纔會被殺死。
connection_aborted和connection_status根本不起作用。 connection_aborted
僅返回0
,即使斷開連接,connection_status也返回CONNECTION_NORMAL
。只有當我使用RabbitMQ時纔會發生。沒有RMQ這個功能運作良好。
ignore_user_abort(false)
也不起作用。
代碼示例:
<?php
use PhpAmqpLib\Channel\AMQPChannel;
use PhpAmqpLib\Connection\AbstractConnection;
use PhpAmqpLib\Exception\AMQPTimeoutException;
use PhpAmqpLib\Message\AMQPMessage;
class RequestsRabbit
{
protected $rabbit;
/** @var AMQPChannel */
protected $channel;
public $exchange = 'requests.events';
public function __construct(AbstractConnection $rabbit)
{
$this->rabbit = $rabbit;
}
public function getChannel()
{
if ($this->channel === null) {
$channel = $this->rabbit->channel();
$channel->exchange_declare($this->exchange, 'fanout', false, false, false);
$this->channel = $channel;
}
return $this->channel;
}
public function send($message)
{
$channel = $this->getChannel();
$message = json_encode($message);
$channel->basic_publish(new AMQPMessage($message), $this->exchange);
}
public function subscribe(callable $callable)
{
$channel = $this->getChannel();
list($queue_name) = $channel->queue_declare('', false, false, true, false);
$channel->queue_bind($queue_name, $this->exchange);
$callback = function (AMQPMessage $msg) use ($callable) {
call_user_func($callable, json_decode($msg->body));
};
$channel->basic_consume($queue_name, '', false, true, false, false, $callback);
while (count($channel->callbacks)) {
if (connection_aborted()) {
break;
}
try {
$channel->wait(null, true, 5);
} catch (AMQPTimeoutException $exception) {
}
}
$channel->close();
$this->rabbit->close();
}
}
會發生什麼:
- 瀏覽器建立連接SSE到服務器。
var es = new EventSource(url);
- Apache2產生新的進程來處理這個請求。
- PHP生成一個新的隊列並連接到它。
- 瀏覽器關閉連接
es.close()
- Apache2不會終止進程並保持原樣。 RabbitMQ隊列不會被刪除。如果我做了一些重新連接,它會產生一堆進程和一堆隊列(1重新連接= 1進程= 1隊列)。
- 我關閉所有選項卡 - 活動進程。我關閉瀏覽器 - 相同的情況。
尋找某種類型的PHP錯誤。還是Apach2?
我用什麼:
- 最後泊塢窗和碼頭工人,組成
- php:7.1.12-apache or php:5.6-apache圖像(這種情況發生在PHP的兩個版本)
一些截圖:
請幫我弄清楚是怎麼回事...
附:對不起我的英語不好。如果您可以找到錯誤或錯字,請在評論中指出它。我會很感激:)
編號進程不會被apache2殺死。這是自2004年以來最古老的錯誤 - https://bugs.php.net/bug.php?id=30301。 'connection_aborted'和'connection_status'函數不起作用。而這些無法解決它。對我來說,最好使用Websocketd(最後用D) –