CodeIgniter RESTful,异步/后台进程

时间:2012-12-03 11:53:03

标签: php codeigniter response

我正在使用codeIgniter RESTful API(https://github.com/philsturgeon/codeigniter-restserver)将信息(json格式)返回到我的android / iphone应用程序。

有一个操作,我发送一些值,如果一切正常我返回200代码作为响应。

现在,我想以相同的方法添加新操作:使用APNS(Apple推送通知服务)和GCM(Google云消息传递)发送此修改的通知。

当我必须发送不超过3-5个通知时效果很好,问题是APNS,因为我必须逐个发送此消息并且需要很长时间,所以我的应用程序收到超时异常(全部发送通知但用户获得错误连接...)

我可以发送200代码响应,然后继续发送此通知吗? (像这样......)

function my_update_method_post(){
   //....GET my POST values
   update($data);
   $this->response(array('result'=>1),200));


   //Send Notifications
   ....
}

提前致谢...

4 个答案:

答案 0 :(得分:2)

我找到了一个适合我的解决方案,因为我不期望任何结果值。如果无法发送通知...我将其记录在我的数据库中。

这是我用来发送“异步”请求的函数(是的,这不是异步请求,但它的工作方式我正在寻找)

function curl_post_async($url, $params)
{
    $post_string = http_build_query($params);
    $parts=parse_url($url);

    $fp = fsockopen($parts['host'],
        isset($parts['port'])?$parts['port']:80,
        $errno, $errstr, 30);

    if(!$fp)
    {
        //Perform whatever logging you want to have happen b/c this call failed!    
    }
    $out = "POST ".$parts['path']." HTTP/1.1\r\n";
    $out.= "Host: ".$parts['host']."\r\n";
    $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
    $out.= "Content-Length: ".strlen($post_string)."\r\n";
    $out.= "Connection: Close\r\n\r\n";
    if (isset($post_string)) $out.= $post_string;

    fwrite($fp, $out);
    fclose($fp);
}

答案 1 :(得分:1)

由于PHP本身不支持线程或异步函数调用,因此您必须使用一种hacky解决方案。 在这里查看我的问题:PHP file_get_contents() follow Content-length header

解决方案是发送Connection: CloseContent-Length标头,然后让客户端知道这些标头(请参阅上面的链接)。例如,在curl的情况下,一旦达到Content-Length就会关闭连接,但是你的PHP脚本仍然在“后台”运行,这样你就可以开始耗费时间了。

亲切的问候,

的Stefan

P.S。如果脚本需要很长时间才能执行,请确保PHP max执行时间不会妨碍

答案 2 :(得分:1)

是的,这是可能的。

您应该查看PHP exec()this链接。您应该在控制器中设置一个函数,以便从命令行调用。然后,您将传入要使用的GCM / APNS数据数组。

此解决方案并不理想,因为您无法告诉客户端所有邮件都已成功发送。您将发回200表示请求已收到确定,这就是全部。

答案 3 :(得分:0)

看看this article。我喜欢这个解决方案,而不是让客户端告诉服务器立即挂断;如果您在服务器端构建此解决方案,则有多种好处。

  1. 您知道一旦客户端断开连接,服务器将继续处理
  2. 客户端仍然可以从服务器收到响应
  3. 修改

    我没有意识到OP在这里无权访问该服务。在这种情况下,我提到的文章没什么价值。这里的问题是服务器需要很长时间才能响应并挂起客户端。为此,我建议curl_multi_init。这允许您同时发出许多请求。