我希望在我的社交网络网站上实现实时通知更新。我已经对comet进行了一些研究,我真的很着迷。
据我所知,这是在comet服务器上发生的基本流程。
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);
?>
上述代码实际上并不能正常运作。问题在于,如果用户发布新评论,当comet脚本正在运行时,它将无法添加到数据库中。这意味着,comet脚本永远不会返回任何json结果,因为sql查询语句中的语句从未得到满足(没有添加具有更新时间戳的新活动)。我的用于发布新评论的ajax代码已经完全可用,所以我知道那不是问题所在。简而言之,“什么也没发生”,也就是没有任何警报或输出到浏览器控制台。
第3次编辑: 我非常困难地解释了“什么也没有发生”的含义,因此我上传了一张图片,展示了当从jquery调用comet脚本时,数据库插入失败的情况(请注意,在通过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次了,任何指导都将是非常好的,因为我一无所获。
为了防止被关闭,我将我的问题总结如下:
有没有更好的实现comet服务器的方法?虽然我不算最有经验的人,但我真的很想学习如何做到这一点。StackOverflow似乎具有此功能并且完美地运行-他们是如何做到的?
我已经尽可能详细地写了我的帖子,我真的非常感谢你们这些了不起的人能够给予指导。一个关于为什么我的代码“无法工作”的建议或有关如何实现此功能的教程链接将是惊人的!提前致谢,对于这个庞然大物般的问题和所有编辑,我表示歉意!