我正在尝试使用ajax发布创建最简单的聊天应用,并尝试使用SSE推送数据。我刚刚遇到SSE并尝试了它。现在的问题是
如何控制服务器何时推送数据,因为它每3秒推送一次数据。
为什么当我选择整个MySQL行只显示浏览器中的最后一行但推送所有内容时(在网络选项卡中选中)
这是我的代码:
的index.html
<script>
var source = new EventSource("server.php");
source.addEventListener("message", function(event){
$("#box").html(event.data);
});
</script>
<script type="text/javascript">
function chat_pressed(){
var chat = $('#chat_text').val();
var data = {action : "send_chat", chat : chat};
$.ajax({
type : "POST",
url : "chat.php",
data : data,
success : function(r){
$('#chat_text').val("");
}
})
}
</script>
<input type="text" id="chat_text" />
<input type="button" onClick="chat_pressed();" value="POST"/>
<br /><hr />
<div id="box"></div>
server.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
include("connect.php");
$sql = $db->prepare("SELECT * FROM chat");
$sql->execute();
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
$chat = $row['chat'];
echo "data: $chat \n\n";
}
ob_flush();
flush();
//sleep(2);
index.html
更改为$("#box").html(event.data);
时{} $("#box").append(event.data);
,它会一遍又一遍地显示所有行。基本上附加。这里发生的事情是,当我保留$("#box").html(event.data);
当我在server.php
上写echo "data:".$chat."<br />"
时,它就没有推动任何东西。
我想要的是控制服务器推送事物,并在表更新时仅将最后一行数据附加到当前数据。而且我想知道echoing
数据的正确方法,因为当divs
等复杂的事情发生时,正如我所理解的那样,所有这些都会变得困难。这里的任何帮助将不胜感激..
答案 0 :(得分:0)
您的server.php进程在发送一位数据后结束。这意味着插座关闭。浏览器看到套接字已经死亡并在3秒后重新连接。这就是为什么看起来它每3秒推送一次数据。相反,你需要更改你的server.php以拥有一个无限循环,其中有一个睡眠,并轮询mysql:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
include("connect.php");
$previousID = 0;
while(true){
$sql = $db->prepare("SELECT * FROM chat WHERE id > ?");
$sql->execute( array($previousId) );
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
$chat = $row['chat'];
echo "data: $chat \n\n";
//TODO: update $previousID here
}
ob_flush();
flush();
sleep(10); //Poll every 10 seconds
}
此(未经测试的)代码还显示了每次只发送新数据的方法。你需要让它更健壮 - 如果收到0行,你可能想发送心跳来告诉客户端最后的轮询时间,例如。
对于第二个问题,您为每个发送的数据调用了消息处理程序,然后执行:
$("#box").html(event.data);
这意味着每个新数据都会覆盖前一个数据;因为所有数据行都在同一时间到达,所以你在屏幕上看到的只是最后到达的数据行。
如果您希望所有行都在屏幕上,请考虑使用<li>
标记和jQuery的append()
。在我的书(PLUG:带有HTML5 SSE的数据推送应用程序 - O'Reilly)中,我经常附加到<pre>
标签,作为查看到达所有数据的快捷方式。