PHP发送推送通知连接失败:111连接被拒绝

Posted

技术标签:

【中文标题】PHP发送推送通知连接失败:111连接被拒绝【英文标题】:PHP Sending Push Notifications Failed to connect: 111 Connection refused 【发布时间】:2018-08-25 07:10:41 【问题描述】:

我正在尝试设置推送通知,我从苹果开发者那里获得了我的证书,无法在我的 ios 应用程序上推送通知,并且我有一个 php 脚本应该发送推送通知。我的托管服务提供商将我帐户的出站端口 2195 列入白名单。但是推送通知仍然不起作用,我收到此错误

连接失败:111 连接被拒绝

我正在使用开发证书,它们已在我的 Apple 开发者帐户中启用。

<?php 

class PushNotifications 

    private static $passphrase = 'PASSPHRASE';

    public function iOS($data, $devicetoken) 

        $deviceToken = $devicetoken;

        $ctx = stream_context_create();

        stream_context_set_option($ctx, 'ssl', 'local_cert', 'Certificates.pem');
        stream_context_set_option($ctx, 'ssl', 'passphrase', self::$passphrase);

        $fp = stream_socket_client(
            'ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

        if (!$fp)
        
            exit("Failed to connect: $err $errstr" . PHP_EOL);
        

        $body['aps'] = array('alert' => array('title' => $data['mtitle'], 'body' => $data['mdesc'],),'sound' => 'default');

        $payload = json_encode($body);

        $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

        $result = fwrite($fp, $msg, strlen($msg));

        fclose($fp);

        if (!$result)
            return 'Message not delivered' . PHP_EOL;
        else
            return 'Message successfully delivered' . PHP_EOL;

    

    private function useCurl(&$model, $url, $headers, $fields = null) 

        $ch = curl_init();
        if ($url) 
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            if ($fields) 
                curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
            
            $result = curl_exec($ch);
            if ($result === FALSE) 
                die('Curl failed: ' . curl_error($ch));
            

            curl_close($ch);

            return $result;
        
    


?>

谁能帮忙?

【问题讨论】:

这是用于生产还是开发? 这是为了开发 【参考方案1】:

确保您仍然没有被阻止(从您的 php 主机运行):

telnet gateway.sandbox.push.apple.com 2195

如果连接被拒绝,那么问题仍然在于您的托管服务提供商或您与 APNS 之间的某个人。

或者这个,如果你没有 shell 访问权限:

fsockopen('gateway.sandbox.push-apple.com.akadns.net', 2195);

【讨论】:

【参考方案2】:

我发现了问题并解决了。

问题出在 .pem 证书中。不知何故,一个文件中有两个证书,用于生产和开发 .pem 文件。带有两个证书的同一个 .pem 文件在存储库中存在很长时间,但 APN 仅在几个月前停止工作。也许苹果方面升级/改变了一些东西。

但是,解决方案是从 .pem 文件中删除第二个证书。之后 APN 开始工作,现在它们也工作了。

【讨论】:

如何从 .pem 文件中删除第二个证书? 请浏览此链接,它可能会对您有所帮助。 ***.com/questions/31441070/… 我刚刚在终端中打开了 .pem,我假设我删除了其中的第二个....-----BEGIN CERTIFICATE-----,第二个呢-- ---开始私钥-----? 好吧,我尝试删除第二个 -----BEGIN CERTIFICATE----- 和第二个 -----BEGIN PRIVATE KEY----- 但这不起作用:(跨度> 所以我要这样做吗? openssl pkcs12 -in old.p12 -out pemfile.pem -nodes openssl pkcs12 -export -in pemfile.pem -name tomcat -out new.p12 然后再转回.pem?【参考方案3】:

希望试试这个,它对你有用。

消息数据

$pushnoti = array();
$pushnoti['type'] = 'message_notification';
$pushnoti['body'] = array( 'message' => "Your Order id Completed");
send_notification_iphone ($deviceToken, $pushnoti);

通知功能

function send_notification_iphone( $deviceToken, $data) 

    // Put your private key's passphrase here:
    $passphrase = self::$passphrase;
    $pem = 'ck.pem';
    $ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'local_cert', $pem);
    // Open a connection to the APNS server
    $fp = stream_socket_client(
        'ssl://gateway.sandbox.push.apple.com:2195', $err,
        $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
    if (!$fp)
        exit("Failed to connect: $err $errstr" . PHP_EOL);
    $message['body'] = $data['body'];
    $body['aps'] = array( 'alert' => $data['body']['message'], 'body' => $data['body'], 'type'=> $data['type'] );
    $body['badge'] =3;
    $body['sound'] ='cat.caf';
    // Encode the payload as JSON
    $payload = json_encode($body);
    // Build the binary notification
    $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
    // Send it to the server
    $result = fwrite($fp, $msg, strlen($msg));
    if (!$result)
        echo 'Message not delivered' . PHP_EOL;
    else
        // Close the connection to the server
        fclose($fp);

【讨论】:

【参考方案4】:

我也遇到了这个错误。以下是您必须记住的事项:

    ios push cert 文件的路径应该是正确的。使用设备令牌检查在线门户并推送证书。 您的服务器已启用 2195 端口。使用 telnet 命令检查终端。

    如果使用,请检查您的 php 版本支持的 ssl

    ssl://gateway.sandbox.push.apple.com

    如果使用

    则为 tls

    tls://gateway.sandbox.push.apple.com

    您在推送或令牌等中发送的数据应等于或小于苹果文档中提到的指定字节。链接在下面提到。

也可以使用api get reference 发送push,开发服务器:

api.development.push.apple.com:443

生产服务器:

api.push.apple.com:443

https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW1

【讨论】:

以上是关于PHP发送推送通知连接失败:111连接被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

MobileFirst APNS 推送通知失败并出现 java.net.SocketException(连接被远程主机关闭)

这个 php 脚本是不是仍可用于使用 APNs 发送测试推送通知? [基于证书的连接]

IOS推送通知连接开启关闭每日限制

在 GCM 中发送推送通知时出现未经授权的错误

nginx:连接到上游时连接()失败(111:连接被拒绝)

PHP IOS 推送通知(权限被拒绝)