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

10

我正在一个网站上集成Facebook登录选项,在使用PHP调用Facebook API时遇到了一些问题。我实际收到的错误如下:

Failed to connect to graph.facebook.com port 443: Connection timed out

我已验证curl调用中的超时值是正确的,尝试通过SSH直接从服务器的命令提示符检查连接(正确响应ping,端口似乎打开并且有进程在侦听等)。然而,我使用了一个我在网上找到的简单curl片段,其他人也遇到过类似问题,我成功地进行了测试,似乎问题是间歇性/不一致的:有时它能够完美快速地工作,有时会加载几秒钟然后出现上述错误。

我非常怀疑错误是出现在Facebook那边,但我无法弄清楚我做错了什么。我之前曾经使用过PHP中的Facebook SDK,这是我第一次看到这个错误。

是否有其他人以前遇到过这个问题并解决了呢?

快速注释:这是我第一次在Symfony项目中使用Facebook,不认为这在这种情况下是相关的,但为了防万一提一下。

相关代码片段:

$fb = new \Facebook\Facebook(['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(\Facebook\Exceptions\FacebookResponseException $e) {
    echo 'Graph returned an error: ' . $e->getMessage();
    exit;
}
catch(\Facebook\Exceptions\FacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}

在这段代码中,任何一个 $fb->get() 调用失败了——有时是第一个调用、有时是图片调用,有时是好友调用。

[更新]

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

* 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

有人有关于这个问题的更多信息或可能的解释吗?

3个回答

4
事实证明,Facebook的SDK中硬编码了 CURLOPT_CONNECTTIMEOUT ,除了常规超时以外 - 这似乎是引起问题的原因。每当我的服务器和Facebook API之间的连接过慢(10秒以上)时,它会超时,因为10秒是SDK中的默认值。
我将此值更改为cURL此选项的默认值,即300,并且它重新开始正常工作。此值设置在FacebookCurlHttpClient类中的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 AppBundle\Lib\Facebook;

class CustomCurlOptsHttpClient extends \Facebook\HttpClients\FacebookCurlHttpClient
{
    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中使用批处理请求。这将有助于加快进程并防止超时。

希望这能帮助其他遇到同样问题的人!


1
我无法评论,但你能提供一些代码吗?很乐意帮助和调试问题。
此外,当某些内容阻止您的请求时,Facebook Graph API确实会返回此错误。例如,许多共享托管服务器上会阻止file_get_contents。
您还应该处理该错误。

嗨Dinesh, 我在原问题中添加了相关片段,但我认为PHP代码本身不是问题所在...另外,file_get_contents和其他类似的函数是允许的,它托管在我拥有根访问权限的VPS上,因此如果需要,我可以在那里检查和更改东西。 - Émile Perron
什么是URL,https://api.facebook.com/restserver.php,我发现你的代码中有一些错误。我建议你先尝试使用Facebook Graph Explorer,并使用cURL或你选择的编程语言中提供的代码。 - Juggernaut
我测试过其中一个URL,因为它在原始代码片段中,但我也尝试了“经典”的URL,并且也出现了间歇性的失败(例如https://graph.facebook.com/等)。 - Émile Perron
我所有的调用都在Graph API Explorer中进行了测试并且正常工作,我认为实际调用不是问题所在。 - Émile Perron

1

这是我正在使用的示例代码片段,对我来说运行良好。

<?php    
include 'configs.php';
    include_once "Facebook/autoload.php";
    $swipe=1;
    $goto=null;
    try {
        if (!isset($_SESSION['FACEBOOK_SESSION_TOKEN'])) {
            $fb = new Facebook\Facebook([
                '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(Facebook\Exceptions\FacebookResponseException $e) {
        echo 'Graph returned an error: ' . $e->getMessage();
        exit;
    } catch(Facebook\Exceptions\FacebookSDKException $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" ,"#####");
   ?>

此外,图形 API 没有 100% 的正常运行时间。请检查您的服务器以确保 curl 正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接