我希望在我的社交网站上实现实时通知更新。我对彗星做了一些研究,我真的很着迷。
据我了解,这是彗星服务器上发生的基本流程。
Webpage:
Sends an ajax request to server when the document is ready.
Server:
Queries the database every x amount of seconds and returns a json string containing results if any are found.
Webpage:
Receives the result of the json string from the server and sends out another ajax request to do the above process again.
通过了解 Comet 的工作流程,我编写了一些 PHP 和 Javascript 代码。
JavaScript 代码使用 jQuery 库并将 ajax 请求发送到服务器,并将当前时间以 unix 时间戳格式作为 GET 参数。
$(document).ready(function(){
var timestamp = Math.round(new Date().getTime() / 1000);
function comet2(){
$.ajax({
type : 'GET',
url : 'comet.activities.php?timestamp=' + timestamp,
async : true,
cache : false,
success : function(data) {
alert("current timestamp "+timestamp)
var json = JSON.parse(data);
if(json !== null){
alert(data);
}
timestamp = json[0].timestamp;
setTimeout('comet2()', 1000);
},
error : function(XMLHttpRequest, textstatus, error) {
setTimeout('comet2()', 15000);
}
});
}
//call the comet function because the page has loaded.
comet2();
});
PHP 代码将通过使用时间戳参数(在本例中为查询中的 unix 时间戳)在数据库中搜索新行来查询新活动。对于此示例,我将结果数量限制为 1。
<?php
set_time_limit(0);
include("models/config.php");
global $mysqli,$db_table_prefix;
$last = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
$results = null;
$flag=true;
$stmt = $mysqli->prepare("SELECT id,timestamp FROM uc_user_activity WHERE timestamp > ? ORDER BY timestamp DESC LIMIT 0,1");
$stmt->bind_param("i", $last);
$stmt->bind_result($id,$timestamp);
while($flag){
$stmt -> execute();
while ($row = $stmt->fetch()){
$flag = false;
$results[] = array(
"id" => $id,
"timestamp" => $timestamp
);
}
$stmt -> close();
usleep(100000);
clearstatcache();
}
echo json_encode($results);
?>
上面的代码实际上并没有“工作”问题是,如果用户发布新评论,当彗星脚本运行时,它将无法添加到数据库中。这意味着彗星脚本将永远不会返回任何 json 结果,因为永远不会满足 sql 查询中的语句(没有使用更新的时间戳添加新活动)。我用于发布新评论的 ajax 代码 100% 正常工作,所以我知道这不是问题所在。简单地说“什么都没有发生”,即没有任何(没有错误)被警告或输出到浏览器控制台。
编辑号 3:我很难解释“什么都没有发生”的意思,所以我上传了一张图片,显示当从 jquery 调用彗星脚本时数据库插入失败(注意文本框是如何被禁用的,而评论是通过ajax发布的)。
我能做些什么呢?我花了几个小时在互联网上搜索试图解决这个问题/找到一个类似的工作示例但无济于事。
如果我将 PHP 代码中的查询更改为:
$stmt = $mysqli->prepare("SELECT id,timestamp FROM uc_user_activity WHERE timestamp **<** ? ORDER BY timestamp DESC LIMIT 0,1");
代替:
$stmt = $mysqli->prepare("SELECT id,timestamp FROM uc_user_activity WHERE timestamp > ? ORDER BY timestamp DESC LIMIT 0,1");
结果会立即通知浏览器窗口,可以再次发布评论并再次调用脚本并显示新帖子。这表明我的代码毕竟“工作正常”,而且看起来查询导致了问题......
谁能看到这里发生了什么?我现在已经编辑了这个问题 7 次,任何指导都会很棒,因为我一无所获。
只是为了避免关闭,这是我的问题,以总结我上面讨论的内容:
有没有更好的方法来实现彗星服务器?我不是最有经验的人,但我真的很想学习如何做到这一点。似乎 StackOverflow 具有此功能并且运行良好 - 他们是如何做到的?
我不可能写出比这更详细的帖子了,我真的很感谢你们这些很棒的人提供的一些指导。关于为什么我的代码“不起作用”的建议或任何解释如何实现它的教程的链接将是惊人的!提前感谢并为这个怪物的问题和所有的编辑道歉!