notifications push ios: Connection reset by peer - apple-push-notifications

I’m trying to do a notifications system for apple devices, but I’m getting the following errors when I try to run it on the server:
Warning: stream_socket_client(): SSL: Connection reset by peer in
/home/empresa/public_html/simplepush/push.php on line 30
Warning: stream_socket_client(): Failed to enable crypto in
/home/empresa /public_html/push/push.php on line 30
Warning: stream_socket_client(): unable to connect to
ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in
/home/empresa /public_html/push/push.php on line 30 Failed to connect:
0
My code is this:
<?php
ini_set('display_errors','On');
error_reporting(E_ALL);
$deviceToken= 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$passphrase = ' ';
$message = 'my first notification';
////////////////////////////////////////////////////////////////////////////////
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
// Open a connection to the APNS server
$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);
What could be happening? Thanks.

I can't be sure of a particular reason
But please make sure, you are not doing any of the below things wrong:
Don't make many connections in parallel. Either reuse the same
connection or close the connection after delivering Push
Notifications. Actually, servers have a limit for maximum number of
parallel connections, which might leave you in trouble, once you
reach threshold. Also Apple suggests leave a connection open unless
you know it will be idle.
Keep your connections with APNs open across multiple notifications; don’t repeatedly open and close connections. APNs treats rapid connection and disconnection as a denial-of-service attack. You should leave a connection open unless you know it will be idle for an extended period of time—for example, if you only send notifications to your users once a day it is ok to use a new connection each day.
Don't send out developer profile tokens to LIVE APNS. Keep
distribution and development app tokens separate. It could result in
error, if you try to send sandbox tokens to LIVE APNS or vice versa.
SOURCE - APNS - notifications push ios: Connection reset by peer PHP

Related

Binance websocket API sends opcode 8 (connection close) 1 second after successful connect & transfer

I'm having a problem with Binance's websocket API closing the connection almost immediately. The connect and websocket upgrade succeeds, and there's (usually) some of the expected data sent back, but the remote end sends websocket opcode 8 (connection close) less than a second after subscribing. Here's some example debug output; note the time between the initial connect and then reconnect is <= 1 second.
*** Connecting to server: stream.binance.com at 2021-05-25 16:06:48 UTC+0
websocket: connecting to ssl://stream.binance.com:9443 with path /ws/btcusdt#trade
websocket: connected
websocket: sent upgrade request
websocket: successful upgrade
Sending message to server: '{"method":"SUBSCRIBE","params":["btcusdt#trade"],"id":1}'
{"e":"trade","E":1621958809390,"s":"BTCUSDT","t":871186927,"p":"37950.99000000","q":"0.08750200","b":6146242615,"a":6146242639,"T":1621958809389,"m":true,"M":true}
{"e":"trade","E":1621958809390,"s":"BTCUSDT","t":871186928,"p":"37948.01000000","q":"0.27946700","b":6146242632,"a":6146242639,"T":1621958809389,"m":true,"M":true}
errstr=Remote sent opcode 8 (close)
*** Connecting to server: stream.binance.com at 2021-05-25 16:06:49 UTC+0
websocket: connecting to ssl://stream.binance.com:9443 with path /ws/btcusdt#trade
websocket: connected
websocket: sent upgrade request
websocket: successful upgrade
Sending message to server: '{"method":"SUBSCRIBE","params":["btcusdt#trade"],"id":1}'
{"e":"trade","E":1621958810172,"s":"BTCUSDT","t":871186935,"p":"37945.47000000","q":"0.00561300","b":6146242792,"a":6146242898,"T":1621958810171,"m":true,"M":true}
{"e":"trade","E":1621958810172,"s":"BTCUSDT","t":871186936,"p":"37945.43000000","q":"0.01233600","b":6146242721,"a":6146242898,"T":1621958810171,"m":true,"M":true}
{"e":"trade","E":1621958810183,"s":"BTCUSDT","t":871186937,"p":"37945.43000000","q":"0.00140200","b":6146242721,"a":6146242907,"T":1621958810183,"m":true,"M":true}
{"e":"trade","E":1621958810199,"s":"BTCUSDT","t":871186938,"p":"37945.36000000","q":"0.00484000","b":6146242644,"a":6146242914,"T":1621958810199,"m":true,"M":true}
{"e":"trade","E":1621958810203,"s":"BTCUSDT","t":871186939,"p":"37945.36000000","q":"0.08219200","b":6146242644,"a":6146242916,"T":1621958810203,"m":true,"M":true}
{"e":"trade","E":1621958810204,"s":"BTCUSDT","t":871186940,"p":"37945.36000000","q":"0.04644700","b":6146242644,"a":6146242917,"T":1621958810204,"m":true,"M":true}
errstr=Remote sent opcode 8 (close)
I'm using a simple PHP websocket client, slightly modified to output additional debug info: https://github.com/paragi/PHP-websocket-client , however the debug output above should be sufficient to show the subscribe process, and all other relevant parameters.
The same client works fine on another exchange's API.
I temporarily modified the client code to ignore opcode 8, but in that instance Binance enforces the close by closing the TCP socket.
I also tried this on a completely different server (located in another country, different ASN) in case it was my local IP/ASN that was the issue. Same problem.
Any ideas? I am new to websockets, and the Binance API, so perhaps I've done something silly. Thanks for any assistance.
EDIT: Here is minimal code to demonstrate the error. Requires https://github.com/paragi/PHP-websocket-client.git
Note: if there's no data returned, try running it a few times. Results are not consistent.
require_once("PHP-websocket-client/websocket_client.php");
// git clone https://github.com/paragi/PHP-websocket-client.git
$server = "stream.binance.com";
$serverport = 9443;
$streamname = "btcusdt#trade";
$t = array("method" => "SUBSCRIBE", "params" => array("$streamname"), "id" => 1);
$uri = "/ws/$streamname";
$message = json_encode($t) . "\n";
echo "\n*** Connecting to server: $server at " . gmdate("Y-m-d H:i:s") . " UTC+0\n";
$sp = websocket_open($server, $serverport,'',$errstr, 30, true, false, $uri);
if ($sp) {
echo "Sending message to server: '" . trim($message) . "' \n";
websocket_write($sp,$message);
while (1) {
$r = websocket_read($sp,$errstr);
echo "$r\n";
if ($r == "") {
echo "errstr=$errstr\n";
die;
}
}
}
?>

Padrino websockets + Heroku; Connection closed before receiving a handshake response

I am using padrino websockets (https://github.com/dariocravero/padrino-websockets) to provide a chat system for my site, and it works great on my local machine. However, after deploying to heroku (free), the websocket won't make a connection and will return
failed: Connection closed before receiving a handshake response
It works fine on localhost, where I am using this to connect:
connection = new WebSocket('ws://localhost:3000/channel');
But, when used on heroku with this:
connection = new WebSocket('ws://******.herokuapp.com:3000/channel');
it returns a handshake error (above)
My implementation server side
websocket :channel do
on :newmessage do |message|
currentAccount = Account.find_by(lastLoginIP: message["ip"]) rescue nil
if currentAccount != nil
broadcast :channel, {
"name" => currentAccount.nickname,
"url" => currentAccount.url,
"image" => currentAccount.image,
"chatmessage" => message["chatmessage"][0..80]
}
end
end
end
inside my main Padrino app.rb, and this in my Procfile. What is going on?
web: bundle exec puma -t 1:16 -p ${PORT:-3000} -e ${RACK_ENV:-production}
Your Websocket port (3000) isn't publicly available on Heroku.
Heroku forwards any requests made to port 80 or port 443 to the dynamic port of your web dyno, stored in the $PORT bash variable.
In your browser (client), try replacing this line:
connection = new WebSocket('ws://localhost:3000/channel');
With this line:
connection = new WebSocket('ws://' + window.document.location.host + 'channel');
Or, if you want to support both SSL and unencrypted Websockets:
ws_uri = (window.location.protocol.match(/https/) ? 'wss' : 'ws') +
'://' + window.document.location.host + 'channel';
connection = new WebSocket(ws_uri)
It should work if both your app and the websocket layer are sharing the same server.

get a new short-lived user access_token

I need to renew a long-lived access token. I read
Renew long lived access token server side topic and wrote a code as follows:
<?php
$code = $_REQUEST["code"];
if(empty($code)) {
$dialog_url = "https://www.facebook.com/dialog/oauth?"
. "client_id=$app_id"
. "&redirect_uri=$my_url"
. "&scope=..."
;
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
else
{
$response = file_get_contents("https://graph.facebook.com/oauth/access_token?"
. "client_id=$app_id"
. "&redirect_uri=$my_url"
. "&client_secret=$app_secret"
. "&code=$code"
);
$params = null;
parse_str($response, $params);
$access_token=$params['access_token'];
$response = file_get_contents("https://graph.facebook.com/oauth/access_token?"
. "client_id=$app_id"
. "&client_secret=$app_secret"
. "&redirect_uri=$my_url"
. "&grant_type=fb_exchange_token"
. "&fb_exchange_token=$access_token"
);
}
?>
On the first invocation it acquires 60-days access token all right. I expect that on the next invocations it would acquire another (may be with the same name) 60-days tokens, and I would see in the Debugger https://developers.facebook.com/tools/debug that issue time and expiration time changes, but the times do not change. What's wrong with my scenario?
Have you compared the tokens to each other? Facebook will send you back the existing access token when the same call is made in less than 24 hours. Also, tokens are set to not expire if you have also requested page tokens for the user. See my answer here: Facebook Page Access Tokens - Do these expire? for more info on this subject.
One way you can be sure to get a new token each time is if you revoke access by making an http DELETE call to /PROFILE_ID/permissions and then requesting a new token. The only bad thing about this is it will require you to put the user through the oAuth dialog again.

IPv6 with perl on windows not working

cross-post http://perlmonks.org/index.pl?node_id=984750
(Possible duplicate of perl windows IPv6 )
I tried following sample example from : https://metacpan.org/module/IO::Socket::IP
use IO::Socket::IP -register;
my $sock = IO::Socket->new(
Domain => PF_INET6,
LocalHost => "::1",
Listen => 1,
) or die "Cannot create socket - $#\n";
print "Created a socket of type " . ref($sock) . "\n";
It is giving output as :
Cannot create socket - no address associated with nodename
I am using ActiveState perl 5.14.2 and have built IO::Socket::IP module on it.
Following is the ping result:
c:\>ping ::1
Pinging ::1 with 32 bytes of data:
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Reply from ::1: time<1ms
Ping statistics for ::1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
If I use the IPv4 style loopback address 127.0.0.1, the above code works well.
I am wondering what I am missing.
Update:
I just cleaned the perl setup and path, and freshly installed perl 5.14.2 from
http://www.activestate.com/activeperl/downloads
and then I tried following simple code:
use strict;
use warnings;
use Socket qw(getaddrinfo SOCK_STREAM AI_PASSIVE );
my ( $err, #res ) = getaddrinfo( "::", 8086, {
socktype => SOCK_STREAM,
flags => AI_PASSIVE,
} );
die $err if $err;
it ended with following error:
no address associated with nodename at c:\IPv6.pl line 10.
But with 127.0.0.1 it returns proper value.
I am using windows 2008 R2 box, a same run on my another windows box also fails.
I just tried to trace this call in Socket.pm, and found that a "fake_getaddrinfo" is getting called instead of the real getaddrinfo. It seems the XSLoader was either not able to find/load getaddrinfo from Socket.dll or Socket.dll didn't at all have the getaddrinfo.
What could be the reason?
A similar code below using Socket6 works properly on the same setup:
use Socket;
use Socket6;
#res = getaddrinfo('::', 8086, AF_UNSPEC, SOCK_STREAM);
while(scalar(#res)>=5){
($family, $socktype, $proto, $saddr, $canonname, #res) = #res;
($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
print ("\nhost= $host port = $port");
socket(Socket_Handle, $family, $socktype, $proto) || next;
bind(Socket_Handle,$saddr ) || die "bind: $!";
listen(Socket_Handle, 5) || die "listen: $!";
($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV);
print ("\nReady for connections \nhost= $host port = $port");
$paddr = accept(Client, Socket_Handle);
}
So I can't even blame the setup or the system dlls. Is there an issue with perl's built-in IPv6 support for windows' activestate build?
As stated by vinsworldcom on perlmonks.org, to make use of IPv6 sockets you do need to have the Socket6 module installed. As soon as you'd install this via cpan, the code snippet will work fine.

Codeigniter's XML-RPC shows no response data

I'm attempting to connect to an XML RPC server with no luck, I am getting an empty response with no debugging information whatsoever. I've switched on set_debug(), but still nothing.
Can anyone tell me why I am getting no response from the server, no error information and no debug information?
$this->load->library('xmlrpc');
$this->xmlrpc->set_debug(TRUE);
$this->xmlrpc->server('https://myurl.com/xmlrpc', 80);
$this->xmlrpc->method('login');
$request = array('param1', 'param2');
$this->xmlrpc->request($request);
echo 'Error: '. $this->xmlrpc->display_error() . '<br/>';
echo 'Response: '. print_r($this->xmlrpc->display_response(), true) . '<br/>';
Even if you type https:// in server method you are still connecting with server via http, look at 2nd parameter - the port you have set is 80.
Just in case.
I forgot to use:
$this->xmlrpc->send_request()
its best used in a conditional statement like:
if ( ! $this->xmlrpc->send_request())
{
echo $this->xmlrpc->display_error();
}
else
{
echo '<pre>';
print_r($this->xmlrpc->display_response());
echo '</pre>';
}

Resources