2017-09-20 30 views
8

Tôi gửi thông báo đẩy từ php tới ios. Nó được làm việc tốt và đây là mã của tôi:PHP: Gửi thông báo đẩy tới ios

$passphrase = ''; 
$badge = 1; 
$path = base_path('path/to/certificate.pem'); 
$ctx = stream_context_create(); 
stream_context_set_option($ctx, 'ssl', 'local_cert', $path); 
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); 
$fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err, 
    $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx 
); 

if (!$fp) { 
    self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "pending", "normal", null); 
} 

//echo 'Connected to APNS' . PHP_EOL; 
$body['aps'] = array(
    'alert' => $message, 
    'badge' => $badge, 
    'sound' => 'default' 
); 
$payload = json_encode($body); 
$msg = chr(0) . pack('n', 32) . pack('H*', $device_token) . pack('n', strlen($payload)) . $payload; 
$result = fwrite($fp, $msg, strlen($msg)); 

//print_r($result);exit; 

if (!$result) { 
    self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "pending", "normal", null, $result); 
} else { 
    self::SavePush($device_token, $message, $device_id, $device_type, $user_id, "sent", "normal", null, $result); 
} 

fclose($fp); 

Bây giờ vấn đề mà tôi đang phải đối mặt là, tôi không thể xác định xem một thông báo lỗi như $result chứa một số nguyên trong mọi trường hợp, một trong hai, thành công hay thất bại. Tôi đã chuyển một chữ số ngẫu nhiên làm mã thông báo và nó trả về số nguyên như 115 hoặc 65 và nó thay đổi, mỗi lần. Vì vậy, !$result sẽ không hoạt động. Làm cách nào để biết liệu thông báo có bị lỗi không?

+0

có thể trùng lặp với https://stackoverflow.com/questions/25830597/how-to-know-push-notification-delivery-status – arunjos007

Trả lời

6

Cuộc gọi đến fwrite() sẽ trả về số byte đã gửi thành công hoặc trả về FALSE nếu có lỗi gửi. Kết quả $ của bạn đang thay đổi vì nó thay đổi với kích thước của thư bạn đang gửi. Vì vậy, khi biết rằng, bạn có thể phỏng đoán rằng nếu $ result === FALSE thì có lỗi và thông báo không thành công. Nếu $ result! == FALSE, thì thông báo đã được gửi thành công. Điều này chỉ xác minh rằng thư đã được gửi qua mạng. Nó không xác minh rằng cấu trúc của thông điệp hoặc tính hợp lệ của các thẻ hoặc bất kỳ thứ gì như thế.

Bây giờ, nếu bạn cố gắng tìm hiểu xem bản thân thông báo đẩy có hợp lệ không và quả táo đã chấp nhận và đang xử lý, thì có thể bạn muốn CURL và HTTP/2 để thực hiện việc này. Làm một tìm kiếm google nhanh chóng tôi đã xem qua trang web này cho thấy một bản demo làm thế nào để làm điều đó. Tôi đã không kiểm tra trang web này http://coding.tabasoft.it/ios/sending-push-notification-with-http2-and-php/ vì vậy không thể cho bạn biết nếu bản demo là chính xác hay không. Đó chỉ là một tìm kiếm nhanh nhưng có thể giúp bạn đi đúng hướng.

+0

Tôi đã thử $ result === false và nó không hoạt động. – Saani

+0

Bạn có ý nghĩa gì khi nó không hoạt động? Bạn có nghĩa là bạn biết một thực tế là fwrite không thành công và bạn đang nói nó không trả về false? Thời gian duy nhất $ result === false là khi fwrite không thành công. http://php.net/manual/en/function.fwrite.php –

+0

vâng, tôi đã chuyển mã thông báo thiết bị này, "ddd" và chắc chắn đó không phải là mã thông báo thiết bị hợp lệ nhưng '$ result === false' không thành công. – Saani

4

Sau khi bạn gửi một cái gì đó để APNS với fwrite, bạn sẽ cần phải fread (hoặc stream_get_contents;)) phản ứng. Cách tốt nhất là sử dụng kết nối non-blocking (stream_set_blocking($fp, 0);) và chờ đợi phản ứng trong vòng giới hạn thời gian đơn giản:

$read = ''; 
$to = time() + 2; // max 2 seconds wait... 
while (!feof($fp)) // ...or end of connection 
{ 
    $r = stream_get_contents($fp); 
    if (strlen($r) > 0) 
     $read .= $r; 
    if (time() >= $to) 
     break; 
    usleep(100000); 
} 

Sau đó, trong $read bạn sẽ phải hoặc là một cái gì đó hoặc không có gì. Một cái gì đó (chính xác với 6 byte) có nghĩa là lỗi ($error = unpack('Ccommand/Cstatus/Nident', $read);). Không có nội dung nào (hoặc nội dung ngắn hơn/dài hơn 6 byte) nghĩa là tin nhắn được gửi thành công.

4

hai xu của tôi để xóa một điểm quan trọng: như Apple tuyên bố, không có "đảm bảo phân phối" khi đẩy hoạt động theo cách này.

Vì vậy, bạn chắc chắn có thể kiểm tra lỗi mạng, như những kẻ khác đã đề xuất nhưng bạn không nhận được thông báo bảo đảm nào. Để có được như vậy, cách duy nhất (dài ..) là kích hoạt một yêu cầu URL trong thiết bị iOS khi nó nhận được một push. Yêu cầu URL này sẽ cập nhật DB của bạn.

Các vấn đề liên quan