My favorites | Sign in
Project Home Wiki Issues Source
READ-ONLY: This project has been archived. For more information see this post.
Search
for
  Advanced search   Search tips   Subscriptions
Issue 7: PushService not detecting fwrite failure
3 people starred this issue and may be notified of changes. Back to list
Status:  New
Owner:  ----


 
Reported by snbenn...@gmail.com, Oct 20, 2009
What steps will reproduce the problem?
1. Send a successful push notification
2. Far end closes socket or socket becomes unusable
3. Try to send another Push notification and fwrite to the socket fails

What is the expected output? What do you see instead?

The fwrite error needs to be caught and a retry on another socket attempted..

What version of the product are you using? On what operating system?
Centos 5.3

Please provide any additional information below.

We were noticing the service hanging.
We solved this partly by adding the following to catch the socket fwrite
error in PushService.php. This now catches 75% of the hangs - there is
still another hang out there which we havent solved yet - we suspect
SendNotification is waiting for ever for a response to the fwrite:-

//Catch fwrite error in SendNotification
function sendNotification($deviceToken, $message)
{
//added catch fwrite error
$apnsMessage = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '',
$deviceToken)) . chr(0) . chr(strlen($message)) . $message;
$fwritten=fwrite($this->apnsConnection, $apnsMessage);
if ($fwritten==0 || $fwritten===FALSE || $fwritten < strlen($apnsMessage))
    {
	error_log(date('Y-m-d H:i')." - fwrite failed:\n".$message."\nTo device:
".$deviceToken."\n return = ".$fwritten."\n", 3, 'PushServiceError.log');
	return -1;
   }
return $fwritten;
}

//Spot the send failure in listenForClients()
function listenForClients()
	{
		$this->serviceConnection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
		socket_bind($this->serviceConnection, $this->serviceHost,
$this->servicePort);
		socket_listen($this->serviceConnection, 10);

		echo 'LISTENING ',$this->servicePort,"\n";

		while($clientSocket = socket_accept($this->serviceConnection))
		{
			socket_write($clientSocket, "OK\n");

			$deviceToken = trim(socket_read($clientSocket, 1024, PHP_NORMAL_READ));
			$message = trim(socket_read($clientSocket, 1024, PHP_NORMAL_READ));

			if(!empty($deviceToken) && !empty($message))
			{
				//SB added catch fwrite error
				if ($this->sendNotification($deviceToken, $message) >= 0)
				{
					socket_write($clientSocket, "SENT\n");
				}
				else
				{
					socket_write($clientSocket, "ERROR\n");
				}
			}
			else
			{
				socket_write($clientSocket, "ERROR\n");
			}
			socket_close($clientSocket);
		}
	}


Mar 6, 2010
#1 egor.egorov@gmail.com
First, Apple states that it will disconnect you in case you send an invalid token which could be the case. In PHP 
there is no sure way to catch the "SSL Clean Shutdown" message, so you are stuck. 

Second, I've found a way to catch the trouble. BEFORE I fwrite() to the socket, I check if feof() is true. If it is, then 
connection is already closed at the remote end and must be reconnected. The hidden catch is that feof() is not 
immediately true after fwrite of the invalid token - it takes some time to detect the shutdown. About a second I 
guess. 

Powered by Google Project Hosting