PHP中的Facebook Graph API出现不一致的错误 - 无法连接到graph.facebook.com端口443:连接超时

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP中的Facebook Graph API出现不一致的错误 - 无法连接到graph.facebook.com端口443:连接超时相关的知识,希望对你有一定的参考价值。

我正在我正在研究的网站上集成Facebook登录选项,并且在用php调用Facebook的API时遇到了一些问题。我得到的实际错误如下:

无法连接到graph.facebook.com端口443:连接超时

我已经验证了curl调用的超时值是正确的,我尝试通过SSH直接从服务器的命令提示符检查连接(ping正确,端口似乎是打开的,进程正在监听它等)。然而,使用我在网上找到类似问题的简单卷曲片段,我设法轻松测试它,似乎问题是间歇性/不一致的:有时它完美无瑕地工作,有时它会加载几秒钟因上述错误而失败。

我非常怀疑这个错误是在Facebook的一面,但我无法弄清楚它是什么我做错了。我以前在PHP中使用过Facebook SDK,这是我第一次看到这个错误。

有没有其他人在遇到这个问题并修复它?

快速说明:这是我第一次在基于Symfony的项目中使用Facebook - 在这种情况下不要认为它是相关的,而是为了以防万一而将其丢弃。

相关摘要:

$fb = new FacebookFacebook(['app_id' => '[withheld]',
                                      'app_secret' => '[withheld]',
                                      'default_graph_version' => 'v2.10',]);
$fb->setDefaultAccessToken($accessToken); # Access token obtained from Facebook Login in JS, passed in post data.

try {
    $basic_info_response = $fb->get('/me?fields=id,first_name,last_name,email,website');

    if ($with_picture)
        $profile_picture_response = $fb->get('/me/picture?width=720&height=720');

    if ($with_friends)
        $friends_response = $fb->get('/me/friends');
}
catch(FacebookExceptionsFacebookResponseException $e) {
    echo 'Graph returned an error: ' . $e->getMessage();
    exit;
}
catch(FacebookExceptionsFacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}

在这段代码中,它在任何$ fb-> get()调用中都失败 - 并不总是相同的,有时在第一个,有时在第一个,有时在朋友一个。

[更新]

大约90%的电话都出现了错误。我尝试通过SSH(curl -v graph.facebook.com)直接在服务器上进行curl调用,得到以下两个结果:

* Rebuilt URL to: graph.facebook.com/
*   Trying 31.13.91.2...
* TCP_NODELAY set
*   Trying 2a03:2880:f01b:1:face:b00c:0:1...
* TCP_NODELAY set
* Immediate connect fail for 2a03:2880:f01b:1:face:b00c:0:1: Network is unreachable
* Connected to graph.facebook.com (31.13.91.2) port 80 (#0)
> GET / HTTP/1.1
> Host: graph.facebook.com
> User-Agent: curl/7.50.2
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< WWW-Authenticate: OAuth "Facebook Platform" "invalid_request" "Unsupported get request. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api"
< Access-Control-Allow-Origin: *
< Pragma: no-cache
< Cache-Control: no-store
< x-fb-rev: 3274377
< Content-Type: application/json; charset=UTF-8
< x-fb-trace-id: A2OYZzFP3v8
< facebook-api-version: v2.4
< Expires: Sat, 01 Jan 2000 00:00:00 GMT
< Vary: Accept-Encoding
< X-FB-Debug: z9FEtq3Rlh8LyFn6pOIBZ5ZMCX+TY1jUD7iZ7ZRZ8/YGAsi035TbCP3qdBzqxDryvjJhKoKxnbAdvcxY/7r3Vg==
< Date: Mon, 04 Sep 2017 19:51:40 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< 
* Curl_http_done: called premature == 0
* Connection #0 to host graph.facebook.com left intact

* Rebuilt URL to: graph.facebook.com/
*   Trying 31.13.91.2...
* TCP_NODELAY set
* Connected to graph.facebook.com (31.13.91.2) port 80 (#0)
> GET / HTTP/1.1
> Host: graph.facebook.com
> User-Agent: curl/7.50.2
> Accept: */*
> 
< HTTP/1.1 400 Bad Request
< WWW-Authenticate: OAuth "Facebook Platform" "invalid_request" "Unsupported get request. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api"
< Access-Control-Allow-Origin: *
< Pragma: no-cache
< Cache-Control: no-store
< x-fb-rev: 3274377
< Content-Type: application/json; charset=UTF-8
< x-fb-trace-id: BrIDaH8D8D5
< facebook-api-version: v2.4
< Expires: Sat, 01 Jan 2000 00:00:00 GMT
< Vary: Accept-Encoding
< X-FB-Debug: tYvsf7Nn2PVnHFkV40UUddjQGKzPl8XKfdNeiqu1CXZck5WuUUlcG9hoCAZQrOX93uS19m2JpAEu9DJ/YhSIeg==
< Date: Mon, 04 Sep 2017 19:54:54 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< 
* Curl_http_done: called premature == 0
* Connection #0 to host graph.facebook.com left intact

有没有人对此问题有任何更多信息或可能的解释?

答案

事实证明,除了常规超时之外,Facebook的SDK中还设置了硬编码的CURLOPT_CONNECTTIMEOUT - 这似乎是导致问题的原因。每当我的服务器和Facebook API之间的连接太慢(10s +)时,它就会超时,因为10s是SDK中的默认值。

我将此值更改为此选项的cURL默认值(即300),然后它再次开始工作。此值在FacebookCurlHttpClient类中的Facebook SDK中以openConnection方法设置。

现在,由于导致连接在某些时候变慢的原因,这仍然是未知的,但至少在发生这种情况时它不再崩溃。

您可以重新定义SDK的cURL包装器的方法,如下所示:https://www.sammyk.me/how-to-inject-your-own-http-client-in-the-facebook-php-sdk-v5#customizing-the-curl-predefined-constants

例如,这是我重新定义的方法,允许在超时之前允许更长的时间段:

<?php

namespace AppBundleLibFacebook;

class CustomCurlOptsHttpClient extends FacebookHttpClientsFacebookCurlHttpClient
{
    public function send($url, $method, $body, array $headers, $timeOut)
    {
        $timeOut *= 5;
        return parent::send($url, $method, $body, $headers, $timeOut);
    }

    public function openConnection($url, $method, $body, array $headers, $timeOut)
    {
        $timeOut *= 5;
        parent::openConnection($url, $method, $body, $headers, $timeOut);

        $options = [
            CURLOPT_CONNECTTIMEOUT => 300,
        ];

        $this->facebookCurl->setoptArray($options);
    }
}

如果您有多个请求一个接一个地请求,您也可以在Facebook SDK中使用批量请求。这将有助于加快这一过程,防止你达到超时。

希望能帮助那些面临同样问题的人!

另一答案

我无法评论,但你能提供一些代码吗?很乐意帮助和调试这个问题。

此外,当某些内容阻止您的请求时,Facebook Graph API会返回此错误。例如,在许多共享主机服务器上阻止了file_get_contents。

您还应该处理错误。

另一答案

这是我正在使用的样本片段并且对我来说工作正常。

<?php    
include 'configs.php';
    include_once "Facebook/autoload.php";
    $swipe=1;
    $goto=null;
    try {
        if (!isset($_SESSION['FACEBOOK_SESSION_TOKEN'])) {
            $fb = new FacebookFacebook([
                'app_id' => APP_ID,
                'app_secret' => APP_SECRET,
                'default_graph_version' => 'v2.5',
            ]);
            $helper = $fb->getRedirectLoginHelper();
            $permissions = ["user_about_me","publish_actions" , "user_photos"];
            $loginUrl = $helper->getLoginUrl( CALLBACK_URL ,  $permissions);
            $swipe=0;

        }
    }
    catch(FacebookExceptionsFacebookResponseException $e) {
        echo 'Graph returned an error: ' . $e->getMessage();
        exit;
    } catch(FacebookExceptionsFacebookSDKException $e) {
        echo 'Facebook SDK returned an error: ' . $e->getMessage();
        exit;
    }?>

Config.php

<?php

    define("CALLBACK_URL", "http://{domain}/facebookredirect.php");
    define("RESULT_PAGE", "http://{domain}//profile.php");
    define("LOGIN_URI" , "http://{domain}//index.html");
    define("APP_ID" , "########");
    define("APP_SECRET" ,"#####");
   ?>

此外,Graph API没有100%的正常运行时间。检查您的服务器是否正常工作。

以上是关于PHP中的Facebook Graph API出现不一致的错误 - 无法连接到graph.facebook.com端口443:连接超时的主要内容,如果未能解决你的问题,请参考以下文章

使用 cURL PHP / Graph API 在 Facebook 中回复评论

Facebook Graph API 电子邮件字段出现问题

使用带有 Graph API 的 PHP SDK 访问 Facebook 事件的 RSVP 列表

Facebook API/PHP - 是不是可以通过 FB Graph API 更改用户的个人资料图片?

Facebook PHP SDK Graph API - 是不是可以访问 PAST 事件?

连接 Facebook Graph API 时 ElasticBeanstalk for PHP 上的 504 网关超时