您的位置:首页 > 编程语言 > PHP开发

PHP中发起异步请求

2016-07-12 00:00 483 查看
摘要: 异步请求

最近OpenSNS在改版,小编作为V3的主力开发人员,就遇到了这样一个问题。

在后台新增系统公告后,要给网站所有用户发送一条公告消息。作为自认为有一些经验的开发者,小编立马考虑了一个问题,那就是"如果用户量在几千、几万、几十万个的时候怎么办?肯定不能使用正常的添加公告-》发送消息-》反馈信息 这种流程"。而是应该用添加公告-》反馈信息-》发送消息(不等待结果)这种流程。那么该怎么实现呢?

通过查询,小编了解到有这些方法:http://my.oschina.net/zzlzheng/blog/707190

最终小编决定尝试curl扩展。

通过下面的代码,小编实现了上述需要的功能

./Application/Admin/Controller/AnnounceController.class.php
//请求调用异步执行发消息方法
private function _sendMessage($announce_id=0)
{
if($announce_id!=0){
$time=time();
$url = U('Core/Announce/sendAnnounceMessage', array('announce_id' => $announce_id,'time' => $time, 'token' => md5($time . C('DATA_AUTH_KEY'))), true, true);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);  //设置过期时间为1秒,防止进程阻塞
curl_setopt($ch, CURLOPT_USERAGENT, '');
curl_setopt($ch, CURLOPT_REFERER, 'b');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_exec($ch);
curl_close($ch);
}
return true;
}

./Application/Core/Controller/AnnounceController.class.php

/**
* 发布公告后,给所有用户发送公告消息
* @return bool
* @author 郑钟良<zzl@ourstu.com>
*/
public function sendAnnounceMessage()
{
$aToken = I('get.token','','text');
$aTime = I('get.time',0,'intval');

if($aTime + 30  < time()){
exit('Error');
}
if($aToken != md5($aTime.C('DATA_AUTH_KEY'))){
exit('Error');
}
ignore_user_abort(true); //即使Client断开(如关掉浏览器),PHP脚本也可以继续执行.
set_time_limit(0); // 执行时间为无限制,php默认的执行时间是30秒,通过set_time_limit(0)可以让程序无限制的执行下去

$aId=I('get.announce_id',0,'intval');

$announceModel=D('Announce');
$announce=$announceModel->getData($aId);
if($announce){
$memberModel=M('Member');
$uids=$memberModel->where(array('status'=>1))->field('uid')->select();
$uids=array_column($uids,'uid');

$content=array(
'keyword1'=>$announce['content'],
'keyword2'=>$announce['create_time'],
);
$messageModel=D('Message');
$messageModel->sendALotOfMessageWithoutCheckSelf($uids,$announce['title'],$content,$announce['link'],null,-1,'Common_announce','Common_announce');
}
return true;
}

写在最后:在进行这部分开发过程中,小编发现,在OpenSNS中curl请求的控制器地址必须是Core模块下的Controller中的方法才行,其他模块的方法就是不行,小编现在还不知道为何,不过小编相信以后一定会找到原因的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息