我创建的服务器发送事件实现中似乎存在一个奇怪的错误。问题似乎出在通过过滤系统的客户端上。问题在于,脚本应该仅在有新信息时才更新应用程序数据流,而不是仅连续重复所有操作。当前,脚本将阻止流重复除收到的最后一条消息以外的所有内容。最后一条消息是唯一无限期重复的消息。
我也尝试在服务器端过滤消息,但这似乎无济于事。我遗漏的任何信息,只要问问,我将非常乐意为您提供。
客户端Javascript
function getMsgs() {
if (typeof(EventSource) !== "undefined") {
var source = new EventSource('');
var last_id;
var used = {};
source.addEventListener('message', function(event) {
if (event.origin != 'http://example.com') {
alert('Error: Unidentified origin!');
return;
} else {
var now_id = event.lastEventId;
if (window.matchMedia("screen and (max-width: 800px)").matches) {
if (last_id != now_id && document.getElementById('content').innerHTML != event.data) {
last_id = event.lastEventId;
if (!used[event.data]) {
document.getElementById('content').innerHTML += event.data;
used[event.data] = 1;
}
}
} else {
if (last_id != now_id && document.getElementById('chatMsgs').innerHTML != event.data) {
last_id = event.lastEventId;
if (!used[event.data]) {
document.getElementById('chatMsgs').innerHTML += event.data;
used[event.data] = 1;
document.getElementById('chat').scrollTop = document.getElementById('chat').scrollHeight; //keep scrollbar at the bottom
}
}
}
}
}, false);
}
服务器端PHP
*
lstMsg
会话是在用户登录时预先设置的<?php
session_start();
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
include "../includes/config.php";
include "../includes/functions.php";
function getMessages($time) {
$con = new PDO(DB_DSN, DB_USERNAME, DB_PASSWORD);
$con->exec("SET CHARACTER SET utf8");
$getLastMsg = "SELECT MAX(`sent`) FROM `messages` WHERE `msg_to` = '$_SESSION[username]' AND `type` = '0' LIMIT 1";
$retrieveTime = $con->query($getLastMsg);
$_SESSION['lstMsg'] = $retrieveTime->fetchColumn(PDO::FETCH_ASSOC);
$getMsgs = "SELECT * FROM `messages` WHERE `msg_to` = '$_SESSION[username]' AND `type` = '0' AND `sent` > '$time' ORDER BY `sent` ASC";
$receivedMsgs = $con->query($getMsgs);
foreach ($receivedMsgs->fetchAll() as $msg) {
$getUI = "SELECT `profile_pic`, `full_name`, `username` FROM `users` WHERE `username` = '$msg[msg_from]'";
$uiQuery = $con->query($getUI);
while ($UI = $uiQuery->fetch(PDO::FETCH_ASSOC)) {
echo "id: {$msg['id']}\n";
echo "data: <article class='post'>\n";
echo "data: <img src='{$UI[profile_pic]}' alt='{$UI[full_name]}' />\n";
echo "data: <section class='pContainer'>\n";
echo "data: <p class='timeAgo'>". Agotime($msg[sent]) ."</p>\n";
echo "data: <a style='position:absolute;' href='/profile?uid={$UI[username]}'>{$UI['full_name']}</a><br />\n";
echo "data: <h4>@{$msg['msg_from']}</h4>\n";
echo "data: <p class='postContent'>{$msg['message']}</p>\n";
echo "data: </section>\n";
echo "data: </article>\n\n";
}
ob_flush();
flush();
sleep(1);
}
}
getMessages($_SESSION['lstMsg']);
?>
最佳答案
我遇到了同样的问题,终于找到了阻止重复发送最后一条消息(来自服务器)的方法。
$sql = "SELECT * FROM `table_name` WHERE `id` > '$_SESSION["id"]'";
$result = mysqli_query($conn, $sql);
while($row = mysqli_fetch_assoc($result)) {
echo $row["data_from_database"];
if($_SESSION["id"] < $row["id"]){
$_SESSION["id"] = $row["id"];
}
}
但是,您必须在页面上设置$ _SESSION [“ id”]变量,该变量正在为SSE建立(调用)连接,否则它将无法正常工作。