我正在研究使用jQuery和PHP对消息系统进行长时间轮询。我很想知道实现这一目标的最佳/最有效的方法。我的基础是Simple Long Polling Example。
如果用户正坐在收件箱页面上,我想提取任何新邮件。我见过的一个想法是在消息表中添加last_checked
列。 PHP脚本看起来像这样:
query to check for all null `last_checked` messages
if there are any...
while(...) {
add data to array
update `last_checked` column to current time
}
send data back
我喜欢这个想法,但我想知道别人怎么想。这是解决这个问题的理想方式吗?任何信息都会有所帮助!
要添加,网站上没有可用的设置数量,因此我正在寻找一种有效的方法。
答案 0 :(得分:8)
是的,您描述的方式是长轮询方法通常如何工作。
您的示例代码有点模糊,所以我想补充一点,您应该在sleep()
循环内执行while
一小段时间,并且每次比较last_checked
时间(它存储在服务器端)和current
时间(这是从客户端发送的)。
这样的事情:
$current = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
$last_checked = getLastCheckedTime(); //returns the last time db accessed
while( $last_checked <= $current) {
usleep(100000);
$last_checked = getLastCheckedTime();
}
$response = array();
$response['latestData'] = getLatestData() //fetches all the data you want based on time
$response['timestamp'] = $last_checked;
echo json_encode($response);
在你的客户端JS你会得到这个:
function longPolling(){
$.ajax({
type : 'Get',
url : 'data.php?timestamp=' + timestamp,
async : true,
cache : false,
success : function(data) {
var jsonData = eval('(' + data + ')');
//do something with the data, eg display them
timestamp = jsonData['timestamp'];
setTimeout('longPolling()', 1000);
},
error : function(XMLHttpRequest, textstatus, error) {
alert(error);
setTimeout('longPolling()', 15000);
}
});
}
答案 1 :(得分:2)
您可以添加last_checked
,而不是将新列添加为last_checked_time
。这样您就可以将数据从last_checked_time
提取到current_time
。
(i.e) DATA BETWEEN `last_checked_time` AND `current_time`
答案 2 :(得分:1)
如果您只有一个用户,那很好。如果你不这样做,你会遇到并发症。你也可以通过这样做来运行一大堆SELECT查询。
由于PHP没有任何跨客户端事件驱动的可能性,我一直坚信PHP和长轮询本身不能正常工作。这意味着您需要每秒/ 2秒/ 5秒检查一次数据库,而不是依赖于事件。
但是,如果您仍想这样做,我会让您的消息传递系统在用户有消息时在目录中写入文件[nameofuser] .txt,并使用此触发器检查消息是否存在。如果文件存在且不为空,则触发请求以获取消息,处理,反馈然后删除文本文件。这将减少您的SQL开销,而(如果您不小心)增加磁盘IO。
结构方面,关联表是目前最好的。创建一个专用于检查状态的新表,其中包含三列:user_id
message_id
read_at
。用法应该是显而易见的。没有在那里的任何组合都是未读的。
答案 3 :(得分:1)
您可以创建名为:checked的列,而不是创建名为last_checked的列。 如果保存数据库中的所有消息,则可以更新数据库中的字段。例如: