彗星和PHP的实时数据更新?

时间:2013-04-08 00:29:13

标签: php push-notification 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.

通过了解彗星如何工作的流程,我编写了一些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脚本永远不会返回任何json结果,因为从不满足sql查询中的语句(没有新的活动添加新的时间戳)。我发布新评论的ajax代码是100%工作,所以我知道这不是问题。简单地说“没有任何反应”,即 - 没有任何内容(没有错误)被警告或输出到浏览器控制台。

修改编号3: 我正在努力解释我的意思是什么'没有发生',所以我上传了一个图像,显示数据库插入失败时从jquery调用彗星脚本(请注意文本框如何在评论被禁用时被禁用通过ajax发布。

enter image description here

我该怎么办?我花了几个小时搜索互联网试图修复此问题/找到一个类似的工作示例但没有用。

如果我将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");

结果立即被提醒浏览器窗口,可以再次发布评论并再次调用脚本并显示新帖子。这表明我的代码“工作正常”,看起来查询导致问题......

enter image description here

谁能看到这里发生了什么?我已经编辑了这个问题7次,任何指导都会很好,因为我无处可去。

所以这不会被关闭,这是我的问题,以总结我上面讨论的内容:

  

有没有更好的方法来实现彗星服务器?我不是   最有经验的人,但我真的想学习怎么做   这个。似乎StackOverflow具有此功能并且可以正常工作   完美 - 他们是怎么做到的?

我不可能在任何进一步细节上写下我的帖子,我真的很感谢你们这些人的指导。关于为什么我的代码“不起作用”的建议或任何解释如何实现这个的教程的链接将是惊人的!在此先感谢并为这个问题的怪物和所有编辑道歉!

2 个答案:

答案 0 :(得分:0)

我的预感是你传递的时间戳值没有返回任何结果。你通过Javascript获得当前时间。查询在此时间戳之后查询所有帖子。

您是否可以尝试打印查询并手动运行相同的查询以确保它从数据库中检索数据?

答案 1 :(得分:0)

因此,有关PHP的Comet的最佳可用教程就在这里。 http://www.zeitoun.net/articles/comet_and_php/start

喜欢它,如果有帮助:)

对于那些想在jQuery链接中使用上述简单聊天解决方案的人来说,这就是解决方案。

<script type="text/javascript">
    var Comet = {};
    Comet.jquery = {
        timestamp: 0,
        url: './backend.php',
        noerror: true,
        initialize: function () {
        },
        connect: function ()
        {
            this.ajax = $.ajax({
                type: "get",
                url: this.url,
                data: {timestamp: this.timestamp},
                success: function (data) {
                    // handle the server response
                    var response = JSON.parse(data);
                    console.log(response);
                    //alert(response.timestamp);
                    Comet.jquery.timestamp = response.timestamp;
                    Comet.jquery.handleResponse(response);
                    Comet.jquery.noerror = true;
                },
                complete: function (data) {
                    // send a new ajax request when this request is finished
                    if (!Comet.jquery.noerror) {
                        // if a connection problem occurs, try to reconnect each 5 seconds
                        setTimeout(function () {
                            Comet.jquery.connect()
                        }, 5000);
                    }
                    else {
                        Comet.jquery.connect();
                    }
                    Comet.jquery.noerror = false;
                }
            });
        },
        disconnect: function ()
        {
        },
        handleResponse: function (response)
        {
            $('#content').append('<div>' + response.msg + '</div>');
        },
        doRequest: function (request)
        {
            $.ajax({
                type: "get",
                url: this.url,
                data: {'msg': request}
            });
        }
    }
</script>