重要编辑:(一天后)
经过测试,我发现这是一个非常糟糕的解决方案。
测试用例:
- 客户端:运行 8 个客户端(在一个浏览器中(Chromium,(k)ubuntu),一个选项卡,8 个 iframe)。
- 服务器 API:Apache 2.0 处理程序
- PHP 版本 5.3.10-1ubuntu3.4
结果:
6 个 SSE 连接打开。但 2 个 SSE 连接未决。在关闭 SSE 客户端之前,服务器中的其他页面无法打开。
但是服务器可以通过 ajax 处理许多客户端(每 1 秒重复一次 ajax)。
老答案:
使用共享内存。
sse.php
<?php
header("Content-Type: text/event-stream\n\n");
header('Cache-Control: no-cache');
$key = "987654";
$permissions = 0666;
$size = 1024;
//Create or open the shared memory segment.
$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);
}
触发器.php
<?php
if (isset($_GET['msg'])) {
$key = "987654";// TODO: how to generate suitable key?
$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 次,则只保存最后一条消息)