我正在尝试设置一个PHP服务器发送事件,这可以正常工作。但是在随机的时间间隔内,它会反复推送相同的数据。
这是一个快速的场景来澄清我所描述的内容:假设我在1:00:00插入了db记录。记录的数据按原样推送。但是,在1:03:00,该记录的数据被第二次推送。然后在1:03:17,再次被推。现在我显示了3个记录实例。
为什么会发生这种情况,以及随机间隔的原因?
我增加了php执行时间,但问题仍然存在。
在浏览器控制台中,我收到此错误:net :: ERR_INCOMPLETE_CHUNKED_ENCODING。
我有这个用于客户端:
<script>
var source = new EventSource('pdo_updates.php');
var pdo_updates;
source.onmessage = function(e) {
pdo_updates = e.lastEventId + '' + e.data + '<br>';
document.getElementById("videoID").innerHTML += pdo_updates;
};
evtSource.close();
</script>
这适用于服务器端:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
function send_msg($id, $msg) {
echo "data: $msg" . PHP_EOL;
echo PHP_EOL;
ob_flush();
flush();
}
$last_event_id = floatval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : False);
if ($last_event_id == 0) {
$last_event_id = floatval(isset($_GET["lastEventId"]) ? $_GET["lastEventId"] : False);
}
$last_id = 0;
try {
$conn = new PDO('mysql:host=localhost;dbname=my_db', $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
while(1) {
$id = $last_event_id != False ? $last_event_id : $last_id;
$stmt = $conn->prepare("SELECT id, message FROM messages WHERE id > :id ORDER BY id DESC LIMIT 1");
$result = $stmt->execute(array('id' => $id));
$stmt->bindValue('id', $id);
if ($result) {
while($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($data) {
send_msg($data['id'], $data['message']);
$last_id = $data['id'];
}
}
}
sleep(1);
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
答案 0 :(得分:2)
因此,在尝试几乎所有与keepalive相关的标头和每个apache超时调整配置后,我最终运行了一个数据包捕获。我发现远程端正在触发TCP重置。我的网站背后是Cloudflare,一旦我禁用Cloudflare,问题部分就消失了。 TCP会话每100秒刷新一次,并且会在发生这种情况时再次显示最后一条消息。这导致浏览器控制台错误:|-------------------------------------|----//---|
|-------------------------------------|----//---|
|-------------------------------------|----//---|
但与此同时,我的提交代码中存在问题。但我不是百分之百确定原因。
net::ERR_INCOMPLETE_CHUNKED_ENCODING
$.ajax({ type: "POST", url: url, data: $("#submitmessage").serialize(), // serializes the form's elements. success: function(data) {
$("#myvideo").val("");
我需要在提交后清除输入字段中的值。从那以后我没有任何重复。