fwrite():SSL操作失败,代码为1. OpenSSL错误消息: error:1409F07F:SSL例程:SSL3_WRITE_PENDING:错误的写入重试在PHP中

问题描述:

I have got same questions in * and tried all answers but no help. I am not getting what is the error.

Here is my function that i am using:

function sendRegistryNotification($message, $deviceToken, $deviceType, $batchcount)
        {               
            $message=$message;
            $batchcount=$batchcount;            
            $path=ABSPATH.'api'.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR.'Certificates2.pem';
            $deviceType = strtolower($deviceType);
            switch ($deviceType) {
                case 'ios':
                   $pemPath = $path; // replace with the path to PEM file
                   $ctx = stream_context_create();
                   stream_context_set_option($ctx, 'ssl', 'local_cert', $pemPath);

                   $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195',
                       $err,
                       $errstr,
                       60,
                       STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT,
                       $ctx);
                       // Create the payload body
                       $body['aps'] = array(
                           'badge' => +$batchcount,
                           'alert' => $message,
                           'sound' => 'default'
                       );
                       $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));
                       var_dump($result);
                       if (!$result)
                       {
                           fclose($fp);
                           return false;
                       }                                       
                       else
                       {
                           fclose($fp);
                           return true;                  
                       }  
                    break;
                case 'android':
                   $message = array("message" => $message,'title'=> 'eyLog','msgcnt'=>$batchcount);
                   // Set POST variables
                   $url = 'https://android.googleapis.com/gcm/send';

                   $fields = array(
                       'registration_ids' => array($deviceToken),
                       'data' => $message,
                   );
                   $headers = array(
                       'Authorization: key='.'AIzaSyDud68-R31c9SPq4dXZblt0JBPi4TBaneQ', // Key For eylog App
                       'Content-Type: application/json'
                   );
                   // Open connection
                   $ch = curl_init();
                   // Set the url, number of POST vars, POST data
                   curl_setopt($ch, CURLOPT_URL, $url);
                   curl_setopt($ch, CURLOPT_POST, true);
                   curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
                   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                   // Disabling SSL Certificate support temporarly
                   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                   curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
                   // Execute post
                   $result = curl_exec($ch);
                   //var_dump($result);
                   if ($result === FALSE) {
                    //   die('Curl failed: ' . curl_error($ch));
                   }
                   // Close connection
                   curl_close($ch);
                   return TRUE;
                    break;
            }
            return true;
        }

Here is the error that i am getting:

{
    "status": "failure",
    "uniquediary_id": "14407503971",
    "message": "fwrite(): SSL operation failed with code 1. OpenSSL Error messages:
error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry"
}

I am not getting why it is happening. and the code only gives error in server in my localhost it is working fine

When you are trying to write to the socket. If something goes wrong, fwrite will return false or 0 (depending on the php version) as the return value. When it happens, you must manage it.

For the above issue the reason is pretty simple: when SSL_Write returns with SSL_ERROR_WANT_WRITE or SSL_ERROR_WANT_READ, you have to repeat the call to SSL_write with the same parameters again, after the condition is satisfied (read/write available on the socket).

Calling it with different parameters, will yield the 1409F07F bad write retry error.

Thanks for replying I found similar solutions in google that you should write to socket again. In m case code was throwing exception so I am managing that. So Now I am doing it like this

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

// Send it to the server
try {                           
    $result = fwrite($fp, $msg, strlen($msg));
}
catch (Exception $ex) {
    // try once again for socket busy error (fwrite(): SSL operation failed with code 1.
    // OpenSSL Error messages:
error:1409F07F:SSL routines:SSL3_WRITE_PENDING)
    sleep(5); //sleep for 5 seconds
    $result = fwrite($fp, $msg, strlen($msg));
    if ($result)
    {
        return true;
    }
    else {
        return false;
    }
}

Now it is not throwing that error in most of the cases. What I found that it happens when socket is busy so I am trying to write again after 5 seconds now. So I guess this should not come again. It is not live yet but in our testing we did not found this issue again. Can you suggest that I am going in right direction? When this code will be live then there will be a huge number of push notifications then in that case will it work fine or is there any other solution in your mind? Thanks for help :)

I get this error many times. To resolve it, just before fwrite(), I added a sleep(5).

Now, every queries are returned with success.