ホームページ > バックエンド開発 > PHPチュートリアル > PHPコードを使用してiOSなどの複数のデバイスにプッシュ情報機能を実装するにはどうすればよいですか?

PHPコードを使用してiOSなどの複数のデバイスにプッシュ情報機能を実装するにはどうすればよいですか?

WBOY
リリース: 2016-06-23 13:55:08
オリジナル
936 人が閲覧しました

phpコードを使用してiOSやその他のデバイスのプッシュ情報機能を実装するにはどうすればよいですか?

プッシュ情報を受信する必要がある端末は6万台から10万台になる場合があり、一度実行することで複数の端末が情報を受信できるようになります。

通りすがりの人は誰でも、役立つ提案をしてくれるでしょう、ありがとう! ! !


ディスカッションへの返信(解決策)

これをphpで実装するのは簡単ではありません。
メッセージが送信されてユーザーに返されるまで接続を維持するために長時間接続を使用することは絶対にお勧めできません。この場合、サーバーに大きな負荷がかかることになります。
この機能を実装するには、ハートビートを使用することをお勧めします。クライアントのブラウザは、サーバーから最新のニュースを定期的に取得します。

また、バックグラウンドを実装するのが python、nodejs、c++ など、PHP ではない場合は、ロングポーリングを使用できます。

これを php を使用して実装するのは簡単ではありません。
ユーザーにメッセージが返されるまで接続を維持するために長時間接続を使用することは絶対にお勧めできません。この場合、サーバーに大きな負荷がかかることになります。
この機能を実装するには、ハートビートを使用することをお勧めします。クライアントのブラウザは、サーバーから最新のニュースを定期的に取得します。

また、バックグラウンドを実装するのが python、nodejs、c++ など、PHP ではない場合は、ロングポーリングを使用できます。


1台のマシンで6万元から10万元を長時間接続するのは不可能です(笑)

これはphpでできることではありません!
php はサーバー側のスクリプトであり、サーバーではなく、ましてやネットワーク オペレーティング システムでもありません

目標を達成するには、モバイル通信オペレーティング システムを適用するだけで済みます

自分でモバイル バージョンに移動するには、ソース コードが必要です-> iPhone さん、たまたま必要な投稿を投稿したフォーラムの友人がいました
実際にその方法を説明します。主なことは、Apple 開発アカウントを使用して証明書を生成することです。 。
ステップ 1
------------
まず、PHP を使用してサーバー側のインターフェイスを開き、それを iPhone に提供して device_token、つまり電話をアプリケーションに登録する必要があります。インストールされている場合は、このインターフェイスに http リクエストを送信し、各マシンの device_token といくつかのパラメーターを送信します。その後、php を使用してそれを受信し、データベースに保存します

ステップ 2
--------- --
phpを使ってデータを読み込み、データベースから登録されているdevice_tokenを指定形式の文字列につなぎ、生成されたApple証明書を持ってきて、Appleが提供するプッシュサービスAPIにソケットリクエストを行います

Keyコード 1:

stream_context_set_option($ctx, 'ssl', 'local_cert', $pemFile);//$pemFile为证书文件,这个你自己上网找找生成步骤,你必须得有个apple开发帐号$ctx = stream_context_create();stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);		 // Open a connection to the APNS server,推送服务api,以下是沙箱环境$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
ログイン後にコピー
ログイン後にコピー

キー コード 2:
				// Create the payload body		$body['aps'] = array(			'alert' => array(		            'body' => $message,			//'action-loc-key' => 'Bango App',		        ),		    'badge' => $badge,			'sound' => 'oven.caf',		);                $deviceTokens = array();		$payload = FMFactory::GetJson()->encode($body);		 $regs = FMFactory::GetQuery()->from("mobile_pn_register as m","m.*")			->where("m.mobiletype='ios' and m.registered_app_id='{$app_record_id}'")			->query();		if(!count($regs))		{			throw new Exception(MOBILE_NOT_REGISTER_PUSH_NOTIFICATION_YET);		}                //根据协议生成请求串		foreach((array)$regs as $reg)		{			$msg = chr(0) . pack('n', 32) . pack('H*', $reg['devicetoken']) . pack('n', strlen($payload)) . $payload;			// Send it to the server			$result = fwrite($fp, $msg, strlen($msg));		} 
ログイン後にコピー
ログイン後にコピー

キー コード 1 のコピーにエラーがあります。 はい、次のようになります

$passphrase = '';$ctx = stream_context_create();stream_context_set_option($ctx, 'ssl', 'local_cert', $pemFile);stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);// Open a connection to the APNS server,推送服务api,以下是沙箱环境$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
ログイン後にコピー

php はメールを送信しますか?押す?

ソースコードが必要な場合は、自分でモバイルバージョンにアクセスしてください ->iphone、フォーラムの友人がたまたま必要なものを投稿していました
私がそれをどうやってやったかも教えてください、それは実際には非常に簡単で、主に Apple Where を使用して開発されましたアカウント証明書を作成するには?
ステップ 1
------------
まず、PHP を使用してサーバー側のインターフェイスを開き、それを iPhone に提供して device_token、つまり電話をアプリケーションに登録する必要があります。インストールされている場合は、このインターフェイスに http リクエストを送信し、各マシンの device_token といくつかのパラメーターを送信します。その後、php を使用してそれを受信し、データベースに保存します

ステップ 2
--------- --
phpを使ってデータベースからデータを読み込み、登録されているdevice_tokenを指定形式の文字列につなぎ、生成されたApple証明書を持ってきて、Appleが提供するプッシュサービスAPIにソケットリクエストを行います

Keyコード 1:

stream_context_set_option($ctx, 'ssl', 'local_cert', $pemFile);//$pemFile为证书文件,这个你自己上网找找生成步骤,你必须得有个apple开发帐号$ctx = stream_context_create();stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);		 // Open a connection to the APNS server,推送服务api,以下是沙箱环境$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
ログイン後にコピー
ログイン後にコピー

キー コード 2:
				// Create the payload body		$body['aps'] = array(			'alert' => array(		            'body' => $message,			//'action-loc-key' => 'Bango App',		        ),		    'badge' => $badge,			'sound' => 'oven.caf',		);                $deviceTokens = array();		$payload = FMFactory::GetJson()->encode($body);		 $regs = FMFactory::GetQuery()->from("mobile_pn_register as m","m.*")			->where("m.mobiletype='ios' and m.registered_app_id='{$app_record_id}'")			->query();		if(!count($regs))		{			throw new Exception(MOBILE_NOT_REGISTER_PUSH_NOTIFICATION_YET);		}                //根据协议生成请求串		foreach((array)$regs as $reg)		{			$msg = chr(0) . pack('n', 32) . pack('H*', $reg['devicetoken']) . pack('n', strlen($payload)) . $payload;			// Send it to the server			$result = fwrite($fp, $msg, strlen($msg));		} 
ログイン後にコピー
ログイン後にコピー

デバイス番号をすべて取り出して配列に入れます。60,000 ~ 100,000 の場合、この配列は大きすぎますか?
この大きな配列をいくつかの小さな配列に分割するより良い解決策はありますか?このような小さなアレイの効率と大きなアレイ全体の効率ではどちらが優れているのでしょうか?

php でメールを送信しますか?押す?

これは IOS プッシュです

次に、送信するために複数の php プロセスを開いて、それぞれが 10,000 項目を送信できます。

次に、送信するために複数の php プロセスを開いて、それぞれが 10,000 項目を送信できます。

プロセスを開始するにはどうすればよいですか?書き方?


次に、送信する複数の php プロセスを開いて、それぞれが 10,000 項目を送信できます。

プロセスを開始するにはどうすればよいですか?書き方?


可以利用cronjob
php -f send_apns.php 1 10000 #往数据库里1至10000的device_token推送消息
php -f send_apns.php 10000 20000
php -f send_apns.php 20000 30000

但是仔细想想,我觉得你还是先别切分进程了,你还是先把功能实现了再说,碰到问题再解决问题
这种情况效率不效率主要在于你和服务器的连接方式,因为是socket直连,非http(当然http也有keepalive),所以你切分进程反而可能还慢,每个进程需要重新建立socket连接。

所以,just do it,骚年。


那你可以开几个php进程发送嘛,一个发送1w条。

怎么开进程?怎么写?

功能现在正在测试两万条,用时需要45分钟左右!太慢了!而且会有十几条发送不成功!这要是真发10万条得发一天了!!!所以需要提高效率啊!
这个切分进程具体怎么用啊?怎么加到你前面的代码里?

如果是linux下跑的php可以用pcntl_fork跑几个子进程运行下看看。
cronjob也可以,不过需要数据库做些设计,意思是每隔一段时间,检查有无要发送的信息,和群发邮件一个道理

不过我觉得20000条45分钟还行吧,10万条怎么会用到1天。。也得看你们服务器连接apple api的速度如何啊。
丢包问题是个大问题,我这边还没远远到往20000台发送这种规模,也没遇到过
这里有个问题
http://stackoverflow.com/questions/12708486/send-push-notification-to-multiple-devices-apns-response-is-negative-after-a-wh
也是丢包问题,貌似是苹果那边认为你的socket连接不活跃,会关闭连接,所以这边的代码是不是有个重连的机制,这个要靠你自己去想了。

如果是linux下跑的php可以用pcntl_fork跑几个子进程运行下看看。
cronjob也可以,不过需要数据库做些设计,意思是每隔一段时间,检查有无要发送的信息,和群发邮件一个道理

不过我觉得20000条45分钟还行吧,10万条怎么会用到1天。。也得看你们服务器连接apple api的速度如何啊。
丢包问题是个大问题,我这边还没远远到往20000台发送这种规模,也没遇到过
这里有个问题
http://stackoverflow.com/questions/12708486/send-push-notification-to-multiple-devices-apns-response-is-negative-after-a-wh
也是丢包问题,貌似是苹果那边认为你的socket连接不活跃,会关闭连接,所以这边的代码是不是有个重连的机制,这个要靠你自己去想了。

foreach((array)$regs as $reg)        {            $msg = chr(0) . pack('n', 32) . pack('H*', $reg['devicetoken']) . pack('n', strlen($payload)) . $payload;            // Send it to the server            $result = fwrite($fp, $msg, strlen($msg));        } 
ログイン後にコピー
我这么写的时候,丢包现象很严重!发几万设备只能发送成功几百个。把$fp放在循环里,丢包还是有,相对少一些。两万设备能有十几个设备不成功!
请问你是发多少个设备呢?

可以试下这样

while(true){   $j = count($regs);   for($i=0;$i<$j;)   {       $msg = chr(0) . pack('n', 32) . pack('H*', $reg[$i]['devicetoken']) . pack('n', strlen($payload)) . $payload;      // Send it to the server      $result = fwrite($fp, $msg, strlen($msg));      if(!$result)      {//发送失败,socket 重连            $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);     }     else     {        $i++;     }        }  break;}
ログイン後にコピー

汗,编辑不了帖子真是麻烦。

while(true){   $j = count($regs);   for($i=0;$i<$j;)   {       $msg = chr(0) . pack('n', 32) . pack('H*', $reg[$i]['devicetoken']) . pack('n', strlen($payload)) . $payload;      // Send it to the server      $result = fwrite($fp, $msg, strlen($msg));      if(!$result)      {//发送失败,socket 重连                  $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);     }     else     {        $i++;     }        }  break; }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

汗,编辑不了帖子真是麻烦。

while(true){   $j = count($regs);   for($i=0;$i<$j;)   {       $msg = chr(0) . pack('n', 32) . pack('H*', $reg[$i]['devicetoken']) . pack('n', strlen($payload)) . $payload;      // Send it to the server      $result = fwrite($fp, $msg, strlen($msg));      if(!$result)      {//发送失败,socket 重连                  $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);     }     else     {        $i++;     }        }  break; }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

 if(!$result)      {//发送失败,socket 重连                  $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);     }
ログイン後にコピー
ログイン後にコピー
要是这么写的话,是否成功的消息写在哪?

ApnsPHP-master

搜下这个吧,我用这个写过,一次推1万,crontab定时发送的,好像没遇到什么情况

我传到linux服务器上测试了,貌似$ctx = stream_context_create();不好用啊。怎么回事?


汗,编辑不了帖子真是麻烦。

while(true){   $j = count($regs);   for($i=0;$i<$j;)   {       $msg = chr(0) . pack('n', 32) . pack('H*', $reg[$i]['devicetoken']) . pack('n', strlen($payload)) . $payload;      // Send it to the server      $result = fwrite($fp, $msg, strlen($msg));      if(!$result)      {//发送失败,socket 重连                  $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);     }     else     {        $i++;     }        }  break; }
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

 if(!$result)      {//发送失败,socket 重连                  $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);     }
ログイン後にコピー
ログイン後にコピー
要是这么写的话,是否成功的消息写在哪?



我传到linux服务器上测试了,貌似$ctx = stream_context_create();不好用啊。怎么回事?
$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);if (!$fp) {fwrite($fps,"Failed to connect: $err $errstr");}运行结果是:Failed to connect:0
ログイン後にコピー

ApnsPHP-master

搜下这个吧,我用这个写过,一次推1万,crontab定时发送的,好像没遇到什么情况



一次推1万 是怎么推的?我这边推100条都很慢,有什么好方法吗?
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート