10.24 2008-12-02 11:14 采纳率: 0%
浏览 481
已采纳

如何实现基本的"长轮询"?

I can find lots of information on how Long Polling works (For example, this, and this), but no simple examples of how to implement this in code.

All I can find is cometd, which relies on the Dojo JS framework, and a fairly complex server system..

Basically, how would I use Apache to serve the requests, and how would I write a simple script (say, in PHP) which would "long-poll" the server for new messages?

The example doesn't have to be scaleable, secure or complete, it just needs to work!

转载于:https://stackoverflow.com/questions/333664/how-do-i-implement-basic-long-polling

  • 写回答

17条回答 默认 最新

  • csdnceshi62 2008-12-02 13:15
    关注

    It's simpler than I initially thought.. Basically you have a page that does nothing, until the data you want to send is available (say, a new message arrives).

    Here is a really basic example, which sends a simple string after 2-10 seconds. 1 in 3 chance of returning an error 404 (to show error handling in the coming Javascript example)

    msgsrv.php

    <?php
    if(rand(1,3) == 1){
        /* Fake an error */
        header("HTTP/1.0 404 Not Found");
        die();
    }
    
    /* Send a string after a random number of seconds (2-10) */
    sleep(rand(2,10));
    echo("Hi! Have a random number: " . rand(1,10));
    ?>
    

    Note: With a real site, running this on a regular web-server like Apache will quickly tie up all the "worker threads" and leave it unable to respond to other requests.. There are ways around this, but it is recommended to write a "long-poll server" in something like Python's twisted, which does not rely on one thread per request. cometD is an popular one (which is available in several languages), and Tornado is a new framework made specifically for such tasks (it was built for FriendFeed's long-polling code)... but as a simple example, Apache is more than adequate! This script could easily be written in any language (I chose Apache/PHP as they are very common, and I happened to be running them locally)

    Then, in Javascript, you request the above file (msg_srv.php), and wait for a response. When you get one, you act upon the data. Then you request the file and wait again, act upon the data (and repeat)

    What follows is an example of such a page.. When the page is loaded, it sends the initial request for the msgsrv.php file.. If it succeeds, we append the message to the #messages div, then after 1 second we call the waitForMsg function again, which triggers the wait.

    The 1 second setTimeout() is a really basic rate-limiter, it works fine without this, but if msgsrv.php always returns instantly (with a syntax error, for example) - you flood the browser and it can quickly freeze up. This would better be done checking if the file contains a valid JSON response, and/or keeping a running total of requests-per-minute/second, and pausing appropriately.

    If the page errors, it appends the error to the #messages div, waits 15 seconds and then tries again (identical to how we wait 1 second after each message)

    The nice thing about this approach is it is very resilient. If the clients internet connection dies, it will timeout, then try and reconnect - this is inherent in how long polling works, no complicated error-handling is required

    Anyway, the long_poller.htm code, using the jQuery framework:

    <html>
    <head>
        <title>BargePoller</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>
    
        <style type="text/css" media="screen">
          body{ background:#000;color:#fff;font-size:.9em; }
          .msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
          .old{ background-color:#246499;}
          .new{ background-color:#3B9957;}
        .error{ background-color:#992E36;}
        </style>
    
        <script type="text/javascript" charset="utf-8">
        function addmsg(type, msg){
            /* Simple helper to add a div.
            type is the name of a CSS class (old/new/error).
            msg is the contents of the div */
            $("#messages").append(
                "<div class='msg "+ type +"'>"+ msg +"</div>"
            );
        }
    
        function waitForMsg(){
            /* This requests the url "msgsrv.php"
            When it complete (or errors)*/
            $.ajax({
                type: "GET",
                url: "msgsrv.php",
    
                async: true, /* If set to non-async, browser shows page as "Loading.."*/
                cache: false,
                timeout:50000, /* Timeout in ms */
    
                success: function(data){ /* called when request to barge.php completes */
                    addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
                    setTimeout(
                        waitForMsg, /* Request next message */
                        1000 /* ..after 1 seconds */
                    );
                },
                error: function(XMLHttpRequest, textStatus, errorThrown){
                    addmsg("error", textStatus + " (" + errorThrown + ")");
                    setTimeout(
                        waitForMsg, /* Try again after.. */
                        15000); /* milliseconds (15seconds) */
                }
            });
        };
    
        $(document).ready(function(){
            waitForMsg(); /* Start the inital request */
        });
        </script>
    </head>
    <body>
        <div id="messages">
            <div class="msg old">
                BargePoll message requester!
            </div>
        </div>
    </body>
    </html>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(16条)

报告相同问题?

悬赏问题

  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型