Я работаю над PHP-скриптом, который периодически проверяет входящие сообщения пользователя для новых сообщений через IMAP. Скрипт оставляет открытое соединение с сервером IMAP и захватывает UID последнего сообщения каждые 5 секунд. Если UID больше, чем первоначально записанный UID сравнения, скрипт отправляет push-уведомление на iPhone пользователя, уведомляя его / ее о наличии нового сообщения, записывает новый UID в качестве UID сравнения и продолжает проверять наличие новых сообщений таким образом. Вот сценарий:
<?php $server = '{imap.gmail.com:993/ssl}'; $login = 'email_address@gmail.com'; $password = 'my_email_password'; $connection = imap_open($server, $login, $password) OR die ("can't connect: " . imap_last_error()); $imap_obj = imap_check($connection); $number = $imap_obj->Nmsgs; $uid = imap_uid($connection, $number); //infinite loop, need to add some sort of escape condition... for(;;){ $imap_obj = imap_check($connection); $number = $imap_obj->Nmsgs; //if there is a new message send push notification if(imap_uid($connection, $number) > $uid){ $uid = imap_uid($connection, $number); $result = imap_fetch_overview($connection,$number,0); $message = $result[0]->subject; $deviceToken = 'xxxxxxxxxxxxxxxxxx'; $passphrase = 'my_secret_password'; $ctx = stream_context_create(); stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem'); 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) exit("Failed to connect: $err $errstr" . PHP_EOL); echo 'Connected to APNS' . PHP_EOL; // Create the payload body $body['aps'] = array( 'alert' => $message, 'sound' => 'default' ); // 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 //echo 'Message successfully delivered' . PHP_EOL; // Close the connection to the server fclose($fp); } sleep(5); } imap_close($connection); ?>
Это работает. Но для меня это кажется ужасно неэффективным. Каждый дополнительный пользователь поддерживает неопределенное соединение с сервером IMAP и проверяет новые сообщения каждые пару секунд, что кажется глупым.
Есть лучший способ сделать это? Либо с примером кода PHP / ссылок на код (который был бы идеальным, и я бы любил вас навсегда), либо в абстрактных терминах (что давало бы подобное, но менее безусловное обожание), кто-то может объяснить лучшие практики для такого рода задач?
Благодаря! Джеймс
Не могли бы вы использовать что-то вроде CRON, чтобы запланировать запуск скрипта каждые 30 секунд, который хранит db-запись последнего UID для каждого пользователя, а затем локально ищет локальный почтовый ящик каждого пользователя (через локальную оболочку, а не подключаться к нему), если конкретный пользователь имеет новое сообщение, нажмите уведомление и обновите последний UID для этого пользователя в БД …
Это предполагает, что PHP-скрипт живет на почтовом сервере и у вас есть root-доступ.