Reputation: 4300
I have a PHP server-like script that runs indefinitely. It connects to APNS (Apple Push Notification Service) with a stream_socket_client object in PHP.
The problem is that while this works most of the time, I cannot figure out how to validate if the connection to APNS is available when I want to send a push notification. The script receives incoming connections and copies the content to APNS.
When it doesn't work, the script reconnects (the return value of stream_copy_to_stream is 0 on 0 bytes written, which triggers reconnect) and then the next incoming token will succeed, but it logs the following and of course does not deliver the message:
PHP Warning: stream_copy_to_stream(): SSL: An established connection was
aborted by the software in your host machine.
Is there any way to detect the above and thus reconnect to APNS before trying to write to the socket.
And doing this before trying to copy to APNS:
if (!$socketObject) {
// reconnect
}
Does not work, as the object still exists (var_dump will print a description). So how can I check if the connection is still open?
Writing anything to the socket that is not a valid token and payload will cause APNS to disconnect.
The code that performs the writing looks like this:
function writeToAPNS($client) {
return stream_copy_to_stream ( $client, $this->connectionAPNS );
}
Where $client
is returned from stream_socket_accept ( $this->socket, -1 )
and $this->socket
is a variable containing the local socket object listening for incoming connections. -1 means there is no timeout when waiting for an incoming connection. When it works this function returns the number of bytes written. When it fails it returns 0.
$this->connectionAPNS
is the object returned from stream_socket_client
when connecting to APNS. This is what I want to check for validity before I perform the stream_copy_to_stream
function.
So basically I want to detect if $this->connectionAPNS
is valid.
I tried dumping the metadata for the connection object, but it doesn't say anything about the validity, only if it's timed out, protocol type etc.
Upvotes: 2
Views: 659
Reputation: 1698
Well, as explained by M.K., this is how UDP works. And by the way, your code works. Your problem is the warning, which is fairly easy to get rid of by adding an @ to your write function. Your code would then look like :
function writeToAPNS($client) {
return @stream_copy_to_stream ( $client, $this->connectionAPNS );
}
Upvotes: 0
Reputation: 9416
Did you see this note in the official stream_socket_client documentation?
UDP sockets will sometimes appear to have opened without an error, even if the remote host is unreachable. The error will only become apparent when you read or write data to/from the socket. The reason for this is because UDP is a "connectionless" protocol, which means that the operating system does not try to establish a link for the socket until it actually needs to send or receive data.
Please try this methiod stream_get_meta_data on your connection to try to detect a difference. I can't test it right now, but it might help you. Especially the timed_out property.
Another option to at least mute the error messages, since you are handling them, is to set an appropriate errno on the stream_socket_client.
Upvotes: 1