重要编辑:(一天后)
经过测试,我发现这是一个非常糟糕的解决方案。
测试用例:
- 客户端:在一个浏览器(Chromium,(k)ubuntu),一个标签页,8个iframe中运行8个客户端。
- 服务器API:Apache 2.0处理程序
- PHP版本5.3.10-1ubuntu3.4
结果:
打开了6个SSE连接。但是有2个SSE连接仍然处于挂起状态。在关闭SSE客户端之前,服务器上的其他页面无法打开。
但是服务器可以通过ajax处理多个客户端(每秒重复ajax)。
旧答案:
使用共享内存。
sse.php
<?php
header("Content-Type: text/event-stream\n\n");
header('Cache-Control: no-cache');
$key = "987654";
$permissions = 0666;
$size = 1024;
$segment = shm_attach($key, $size, $permissions);
$msg = ' null ';
$last_time = 0;
$time = 0;
while (1) {
if (shm_has_var($segment, 0)) {
$time = shm_get_var($segment, 0);
}
if (shm_has_var($segment, 0)) {
$msg = shm_get_var($segment, 1);
}
$now = time();
if ($last_time < $time) {
$last_time = $time;
echo 'data: msg(' . $msg . ') time(' . $time . ')';
echo "\n\n";
}
ob_flush();
flush();
sleep(1);
}
trigger.php
<?php
if (isset($_GET['msg'])) {
$key = "987654";
$permissions = 0666;
$size = 1024;
$segment = shm_attach($key, $size, $permissions);
$time = time();
$msg = $_GET['msg'];
shm_put_var($segment, 0, $time);
shm_put_var($segment, 1, $msg);
echo $time;
}
这种方式的缺点:
- 一秒钟的延迟
- 长时间开放连接,导致不可扩展性。
在我的实现中,sse.php 每秒只发送最后一条消息。但是您可以改进它并使用数据库。(如果 trigger.php 在一秒钟内被调用了 3 次,则只保存最后一条消息)