Too many bytes written
I've managed to setup ApnsPHP and get it to work; messages are sent and received as expected.
However, there's this peculiar error:
array (
'identifier' => 1,
'statusCode' => 999,
'statusMessage' => 'Internal error (112 bytes written instead of 101 bytes)',
),
This goes for three times, after the third it gives up:
Wed, 22 Apr 2015 17:11:57 +0200 ApnsPHP[63774]: INFO: Trying ssl://gateway.sandbox.push.apple.com:2195...
Wed, 22 Apr 2015 17:11:58 +0200 ApnsPHP[63774]: INFO: Connected to ssl://gateway.sandbox.push.apple.com:2195.
Wed, 22 Apr 2015 17:11:58 +0200 ApnsPHP[63774]: INFO: Sending messages queue, run #4: 1 message(s) left in queue.
Wed, 22 Apr 2015 17:11:58 +0200 ApnsPHP[63774]: WARNING: Message ID 1 [custom identifier: Message-Badge-3] has 3 errors, removing from queue...
And yet, all three messages are received on the device.
What gives?
Is this reproducible with a particular message or it's a sporadic error?
This was 100% reproducible for me, with every message i tried (though i only tried a few with some shared fields). The most recent looks like this:
ApnsPHP_Message::__set_state(array(
'_bAutoAdjustLongPayload' => true,
'_aDeviceTokens' =>
array (
0 => 'fffab12acadav12a1337',
),
'_sText' => '21 unread messages',
'_nBadge' => 21,
'_sSound' => 'default',
'_sCategory' => NULL,
'_bContentAvailable' => NULL,
'_aCustomProperties' =>
array (
'message' => '21 unread messages',
),
'_nExpiryValue' => 30,
'_mCustomIdentifier' => 'Message-Badge-3',
))
So far i've workarounded it by disabling the check here, but now it seems the message above no longer causes the error. :|
I think that too, I wonder if @Anarchid could test that change...
Documentation says it should be as defined by RFC 4627. So most likely:
$nLen = mb_strlen($aMessage['BINARY_NOTIFICATION'], 'UTF-8');
Excerpt from rfc:
3. Encoding
JSON text SHALL be encoded in Unicode. The default encoding is
UTF-8.
Since the first two characters of a JSON text will always be ASCII
characters [RFC0020], it is possible to determine whether an octet
stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
at the pattern of nulls in the first four octets.
00 00 00 xx UTF-32BE
00 xx 00 xx UTF-16BE
xx 00 00 00 UTF-32LE
xx 00 xx 00 UTF-16LE
xx xx xx xx UTF-8
@ghispi you want to send the raw binary, hence you want the length in bytes not the length in chars.
True, got confused by the mb_. So in such case simple strlen should work correctly. Not sure why mb_ with latin1 was suggested.
Because many use mbstring.func_overload=2 in multi-lingual projects. You can find solution in the user contributed note in PHP Manual about mb_strlen.
Ok, but I mean why changing currently used strlen to mb_strlen with such weird setup when strlen does exactly what we need. Documentation implicitly says:
Note:
strlen() returns the number of bytes rather than the number of characters in a string.
If mbstring.func_overload=2, the strlen() is overloaded to mb_strlen() and return number of chars (not bytes).
Ahhh, I never encountered this option but it makes sense. Sorry for the commotion and thanks for explaining.
In such case I'd propose something more flexible which will work if one doesn't have mbstring.
if ((int) ini_get('mbstring.func_overload') & 2) {
$nLen = mb_strlen($aMessage['BINARY_NOTIFICATION'], 'latin1');
} else {
$nLen = strlen($aMessage['BINARY_NOTIFICATION']);
}
There is some bug in php (fixed for php7 alpha) which might cause some of the errors here.
The issue has disappeared for me for some (quite long) time and then recently resurfaced.
Since i could not simply upgrade to php 7, i've tried @ghispi's patch from https://github.com/immobiliare/ApnsPHP/issues/88#issuecomment-111251202 instead.
It seems to work wonderfully thus far.