Получение ответа mysql select с SSE

Я пытаюсь использовать EventSource для создания живого чата с подключением 1: 1. У меня настроен источник событий, и, судя по инструментам разработчика, он открыт и работает, однако данные ответа не отображаются из файла PHP.

PHP:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

session_start(); // Starting Session
include 'dbconnect.php';
include 'Session.php';

$messageuserid = $_GET['messageuserid'];

$RunSqlGM = "SELECT * FROM messages WHERE (SUsername = '$Session_Username' AND RUsername = '$messageuserid') OR (SUsername = '$messageuserid' AND RUsername = '$Session_Username')";
$getmessagethread = mysqli_query($con,$RunSqlGM)or die(mysqli_error());

while($MessageRows = mysqli_fetch_array($getmessagethread)) {
    $MSUsername = $MessageRows['SUsername'];
    $MRUsername = $MessageRows['RUsername'];
    $MSender = $MessageRows['Sender'];
    $MessageContent = $MessageRows['Message'];
    $TimeStamp = date("g:ia \o\\n l jS F Y", strtotime($MessageRows["Time"]));


    if ($MSender === $Session_Username) {
        echo "<table class='messagebubbleright'>";
            echo "<tr><th></th></tr>";
            echo "<tr>";
                echo "<td class='inforight'>$MSender<br>$TimeStamp</td>";
            echo "</tr>";
            echo "<tr>";
                echo "<td class='bubbleright'>$MessageContent</td>";
            echo "</tr>";
        echo "</table>";
        flush();
    } else {
        echo "<table class='messagebubbleleft'>";
            echo "<tr><th></th></tr>";
            echo "<tr>";
                echo "<td class='infoleft'>$MSender<br>$TimeStamp</td>";
            echo "</tr>";
            echo "<tr>";
                echo "<td class='bubbleleft'>$MessageContent</td>";
            echo "</tr>";
        echo "</table>";
        flush();
    }
}
mysqli_close($con); // Connection Closed
?>

И js, который вызывает источник события, содержится в этой функции, которая запускается нажатием кнопки.

JS:

function GetMessages(GetMUserID) {
    if (typeof(EventSource) !== "undefined") {
        var source = new EventSource("db/getmessages.php?messageuserid=" + GetMUserID);
        source.addEventListener("open", function() {
            $("#readmessagearea").html("Getting server updates");
        });

        source.addEventListener("message", function(event) {
            $("#readmessagearea").html(event.data);
        });

    } else {
        $("#readmessagearea").html("Sorry, your browser does not support server-sent events...");
    }
}

Любая помощь или руководство будет принята с благодарностью. Я относительно новичок в SSE, но из того, что я вижу, это должно работать.

1 ответ

Решение

Есть несколько проблем с вашим кодом PHP. Легко исправить это то, что лучше изменить flush() в @ob_flush();@flush(), ob_flush() убедитесь, что PHP ничего не буферизирует, и @ Знаки просто гарантируют, что вы не получите предупреждающее сообщение, если буферизация не используется.

Вторая проблема заключается в том, что протокол SSE минимален, но не настолько минимален! Вам необходимо добавить к сообщению префикс "data:" и добавить суффикс "\n\n". Ваш HTML не включает в себя какие-либо собственные переводы строк, поэтому я думаю, что он будет работать. (Если нет перевода строки в $MessageContent или любые другие динамические данные... Я бы порекомендовал некоторую фильтрацию данных не только по возврату каретки, но и по тегам HTML, так как ваш текущий код уязвим для встроенных атак HTML.)

Другой подход: альтернативой может быть отправка только объекта JSON, содержащего $MessageRows["Time"], $MSender, $MessageContent и т. д. и иметь клиент JavaScript для создания HTML. Это более гибко (например, клиенты в разных странах могут иметь свой собственный формат меток даты, макеты могут быть изменены и т. Д. Без необходимости прикасаться к внутреннему интерфейсу), но переносят больше работы на внешний интерфейс.

Другие вопросы по тегам