php+jquery实现信息推送

背景:一直都觉得信息推送是个很实用的功能。以前想到的最初实现方案是:用ajax隔段时间请求一次后台,由后台取出最新消息后作为返回值给ajax回调展示。今天看到了一个不太一样的解决方案:在php端通过while判断信息有没有发生变更,有则返回给前台展示,展示完后继续发送ajax请求给php后台监视信息;没有的时候,php端while就保持循环监视信息状态,这样请求没有结束,ajax的状态不会完成,也就不用重新发送请求了。

两种方案后来分析了下,大致结果如下

    第一种隔段时间发送一次的,因为请求频率的问题,必然导致请求次数多。但是这种的每个请求都会很快放开,不需要监视信息变化,只关注请求进来时的信息就可以了。

    第二种由php端通过while轮询监视信息是否变化,有变化的时候结束请求,返回给ajax显示,再发送下一次的监视请求;没变化则while循环一直监视。这种方案的话,会大大的减少请求次数问题,但是会导致每个用户对应一个服务器端php监视业务。另外php是没有多线程概念的,用apache的时候有个可以限制最大访问量的设置项MaxRanges。这些问题考虑进去的话会导致一些服务器端同时访问量超标的问题。

   第三种听同事谈到的strophe.js是用于解决web im的已封装好插件。(应用的话之后在写)

备注:以上两种方案,具体应用的话,可能还是需要看场景取舍吧

第一种方案的代码,就略了(主要是while,setTimeout,ajax,递归调用之类的)。和下面第二种应用的代码很多会相同的。

上第二种代码:

<?php
// 设置请求运行时间不限制,解决因为超过服务器运行时间而结束请求
ini_set("max_execution_time", "0");

$filename  = dirname(__FILE__).'/data.txt';
$msg = isset($_GET['msg']) ? $_GET['msg'] : '';

// 判断页面提交过来的修改内容是否为空,不为空则将内容写入文件,并中断流程
if ($msg != '')
{
    file_put_contents($filename,$msg);
    exit;
}

/* 获取文件上次修改时间戳 和 当前获取到的最近一次文件修改时间戳
 * 文件上次修改时间戳 初始 默认值为0
 * 最近一次文件修改时间戳 通过 函数 filemtime()获取
 */
$lastmodif    = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
clearstatcache();  // 清除文件状态缓存
$currentmodif = filemtime($filename);

/* 如果当前返回的文件修改unix时间戳小于或等于上次的修改时间,
 * 表明文件没有更新不需要推送消息
 * 如果当前返回的文件修改unix时间戳大于上次的修改时间
 * 表明文件有更新需要输出修改的内容作为推送消息
 */
while ($currentmodif <= $lastmodif)
{
    usleep(10000);     // 休眠10ms释放cpu的占用
    clearstatcache();  // 清除文件状态缓存
    $currentmodif = filemtime($filename);
}

// 推送信息处理(需要推送说明文件有更改,推送信息包含本次修改时间、内容)
$response = array();
$response['msg'] = file_get_contents($filename);
$response['timestamp'] = $currentmodif;
echo json_encode($response);
flush();
?>
html页面代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Comet demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="./jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="./json2.js"></script>
<script>
    var timestamp = 0;
    var url = 'backend.php';
    var error = false;
    // 通过ajax建立和php端处理函数的连接(通过递归调用建立长时间的连接)
    function connect(){
        $.ajax({
            data : {'timestamp' : timestamp},
            url : url,
            type : 'get',
            timeout : 0,
            success : function(response){
                var data = JSON.parse(response);
                error = false;
                timestamp = data.timestamp;
                if (data.msg != undefined && data.msg != "")
                {
                    $("#content").append("<div>" + data.msg + "</div>");
                }
            },
            error : function(){
                error = true;
                setTimeout(function(){ connect();}, 5000);
            },
            complete : function(){
                if (error)
                    // 请求有错误时,延迟5s再连接
                    setTimeout(function(){connect();}, 5000);
                else
                    connect();
            }
        })
    }
    // 发送信息
    function send(msg){
        $.ajax({
            data : {'msg' : msg},
            type : 'get',
            url : url
        })
    }
    // 创建长时间的连接
    $(document).ready(function(){
        connect();
    })
</script>
</head>
<body>
    <div id="content"></div>
        <form action="" method="get" 
οnsubmit="send($('#word').val());$('#word').val('');return false;">
            <input type="text" name="word" id="word" value="" />
            <input type="submit" name="submit" value="Send" />
        </form>
    </body>
</html>
需要导入js资源:jquery,json2.js


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值