私はこのコードを持っています(サーバー側のイベントを使用しますが、問題は動作しないフラッシュです):
<?php
class Events {
function __construct($fn, $options=array()) {
$settings = array_merge(array(
'headers' => array(
'Content-Type' => 'text/event-stream',
'Cache-Control' => 'no-cache',
'Connection' => 'keep-alive'
),
'retry' => 2000
), $options);
foreach($settings['headers'] as $header => $value) {
header("$header: $value");
}
$lastId = intval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : 0);
echo ":" . str_repeat(" ", 2048) . "\n";
echo "retry: " . $settings['retry'] . "\n";
$id = $lastId;
$i = 0;
foreach ($fn($id) as $value) {
echo "id:" . $id++ . "\n";
echo "data: " . $value . "\n\n";
ob_flush();
flush();
if ($i++ == 10) {
break;
}
}
}
}
if (isset($_SERVER['HTTP_ACCEPT']) && preg_match("%text/event-stream%", $_SERVER['HTTP_ACCEPT'])) {
new Events(function($id) {
while(true) {
$array = array("Foo", "Bar", "Baz", "Quux");
yield json_encode(array("message" => $array[array_rand($array)]));
sleep(1);
}
});
} else { ?><!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Leash</title>
<meta name="Description" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
var source = new EventSource("/EventSource.php");
source.addEventListener("message", function(message) {
console.log(JSON.parse(message.data).message);
});
</script>
<body>
<textarea></textarea>
</body>
</html><?php } ?>
wampサーバーでローカルに動作しますが、共有ホスティングでは動作しません.php情報にこれがあります:
Server API CGI/FastCGI
Directive Local Value Master Value
output_buffering 4096 4096
ob_start()
それを変更することはできません。スクリプトにも追加してini_set('output_buffering', 0)
削除しようとしましob_flush
たが、それは役に立ちませんでした。
また、ディレクトリの .user.ini で output_buffering を 0 に設定しようとしましたが、php 情報はローカル値が 0 であることを示していますが、サーバー側のイベントはまだ機能しません。すべてのイベントを一度に取得し、開発者ツールは次のように言い(pending)
ます10秒後に終了するまで空のタイプ。
これを修正する方法を知っている人はいますか?
編集:
コードを再度実行しようとしましたが (数年後、Fedora/Linux で)、同じ結果が得られました。Gzip は有効になっていませんが、最後にメッセージが表示されます。
私はもう試した:
- ヘッダーを追加
'X-Accel-Buffering' => 'no'
- も追加
echo "event:". $event ."\n";
成功せずに。
whileループを使用するとサーバー側のPHPイベントページが読み込まれないのを見ていましたが、解決策は機能しませんでした。コードはOPと同じエラーを返します(彼には担当者があまりいないため、おそらくSOでアクティブではありません)、私の少なくともイベントを表示していますが、ループを壊しています。彼のコードには無限ループがあります。
これは、サーバー (Fedora) によって送信されるヘッダーです。
Cache-Control: no-cache
Connection: keep-alive, Keep-Alive
Content-Type: text/event-stream;charset=UTF-8
Date: Tue, 17 Sep 2019 07:40:44 GMT
Keep-Alive: timeout=5, max=92
Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1c
Transfer-Encoding: chunked
X-Accel-Buffering: no
X-Powered-By: PHP/7.2.22
http://demo.howopensource.com/sse/の単純なコードでも同じことが起こります
私のphp.iniにはこれがあります:
$ grep -E 'user_ini|output_buffer|zlip.' /etc/php.ini | grep -v '^;'
user_ini.filename = ".user.ini"
output_buffering = 4096
だから私も試してみました、.user.init
ファイルを次のように設定します:
output_buffering = 0
と
output_buffering = Off
しかし、それもうまくいきませんでした。スクリプトはすべてを一度に返すのを待っています。この記事のコードStreaming PHP - PHP、Apache、Nginx、および Varnish で出力バッファリングを無効にする その phpinfoを使用する$string_length = 4096;
と、出力バッファがこのディレクトリに対してローカルで無効になっていると言えます。
EDIT2:
私の共有ホスティングhttps://jcubic.pl/01.php?size=100でフラッシュが機能しているようですが、フラッシュが機能しないため、Fedora でローカルにテストすることはできません。
これが私のローカルphpinfo出力へのリンクです: https://jcubic.pl/phpinfo().html