検索
ホームページphp教程php手册Codeigniter フレームワークに基づく APNS バッチ プッシュ - Ding Dong、水道メーターを確認してください

最近、私のアルバイト先がクラウドファンディングを成功させたワイヤレスドアホンのメッセージプッシュに問題があり、その結果、一部のユーザーがプッシュメッセージを受信できなくなってしまい、本当に困っています。私が自分で提供したバックエンド サービスは会社の評判に影響します。私たちのニーズを簡単に紹介します。その会社は、誰かがドアの外でドアベル スイッチを押すと、信号を発します。家の中の受信ゲートウェイが信号を受信すると、ユーザーの携帯電話にメッセージがプッシュされます。つまり、所有者は、誰かが家のドアホンを押したことがわかります。彼は家にいません。ここでバックグラウンドで解決する必要がある問題は、APNS プッシュ用のプロバイダーを構築することです。メッセージを Apple 携帯電話にプッシュするには、Apple が設計したメカニズムに従ってメッセージを Apple の PUSH サーバーにプッシュする必要があるからです。各携帯電話は deviceToken に対応します。ここでの説明の焦点は、このプラットフォームを構築する方法ではありません。国内のインターネットにはすでにかなりの数のチュートリアルがあります。たとえば、次を参照できます: iOS プッシュの作り方を段階的に教えます

""

オンラインチュートリアルのほとんどは合理的ですが、それらは携帯電話で動作します。つまり、当社が設計した製品では、同じアカウントを携帯電話端末に一度にプッシュすることができます。携帯電話で複数のデバイスにログインします(バックグラウンドでの制限がないため、理論的には無数にあります)。また、同社の製品は、各携帯電話に対応する共有機能も備えています。つまり、メイン ユーザーは他のユーザーとデバイスを共有でき、他のユーザーが別のデバイスで同時にログインでき、誰かがドアベルを鳴らすと、共有ユーザーを含むログインしているすべてのユーザーにメッセージがプッシュされます。 , つまり、多くの携帯電話端末に一括でプッシュされることになります。もちろん、ここで示した例は、すべての問題が 1 つの質問に抽象化されています。deviceToken を格納するための配列を与えてください。 APNS はどのようにして複数のユーザーにバッチでプッシュしますか?

まず、ユーザーのプッシュ トークン (deviceToken) を保存するデータベースを設計します。簡単にするために、このテーブルにはフィールドが 2 つだけあります。

client_idデバイストークン1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

ここでは CodeIgniter3 フレームワークを使用して、ユーザーの deviceToken データを管理する新しいモデルを作成します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
// ios推送令牌管理
class Apns_model extends CI_Model
{
    public function __construct()
    {
        $this->load->database();
    }
    /**
     * 新建推送令牌
     * create a apns如果已经存在就更新这个deviceToken
     * $data is an array organized by controller
     */
    public function create($data)
    {
        if($this->db->replace('tb_apns', $data))
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    //删除某个用户的推送令牌
    public function delete($user_id)
    {
        
        if(isset($user_id)){if(isset($user_id)){
            $result=$this->db->delete('tb_apns', array('client_id' => $user_id)); 
            return TRUE;           
        }else{else{
            return FALSE;
        }
    }
    //根据推送令牌删除推送令牌
    public function deletebytoken($token)
    {
        
        if (isset($token)) {if (isset($token)) {
            $result=$this->db->delete('tb_apns', array('deviceToken'=>$token));
            return TRUE;
        }else{else{
            return FALSE;
        }
    }
    //查询某个用户的iso推送令牌
    public function get($client_id)
    {
        $sql = "SELECT deviceToken FROM `tb_apns` WHERE `client_id`='$client_id'";
        $result = $this->db->query($sql);
        if ($result->num_rows()>0)
        {
            return $result->result_array();
        }
        else
        {
            return FALSE;
        }
    }
}

私のバックエンドの最初のバージョンでは、オンライン チュートリアルによれば、メッセージはほとんど一度に 1 つの端末にプッシュされ、取得したすべての deviceToken を $deviceTokens 配列に格納する必要がありました。メッセージの場合は、for ループを使用して配列から deviceToken を順番に取り出してプッシュし、カウントし、すべてのプッシュが成功した場合に true を返します。この方法には問題はないようで、テストは成功したので、直接オンラインにアクセスしました (主な理由は、プッシュ機能のステータスが非常に高くなるような製品を会社が突然リリースするとは予想していなかったからだ。私はずっとオプションだと思っていました)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function _send_apns($deviceTokens,$message)
    {
      // Put your private key's passphrase here:密语
       $passphrase = 'xxxxx';
           ////////////////////////////////////////////////////////////////////////////////
       $ctx = stream_context_create();
       stream_context_set_option($ctx, 'ssl', 'local_cert', 'xxxx.pem');
       stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
       // Open a connection to the APNS server
       $fp = stream_socket_client(
           'ssl://gateway.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);
       <code class="php variable">$num=count($deviceTokens);
       $countOK=0;//统计发送成功的条数
       for($i=0;$i<code class="php variable">$num;$i++)
       {
           $deviceToken=$deviceTokens[$i];
           $deviceToken=preg_replace("/s/","",$deviceToken);//删除deviceToken里的空格
        // 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)
        
           {
               $countOK++;
           
           }}
       }
      // Close the connection to the server
       fclose($fp);
       if($countOK==<code class="php variable">$num)
           return TRUE;
       else
           return FALSE;
   }

後のプッシュで一連の問題を引き起こしたのは上記のコードでした。

最初の大きな問題は: デフォルトでは、すべてのプッシュ トークンが有効です。実際、ユーザーがアプリを直接削除するか、アプリをアップグレードすると、バックグラウンド データベースの deviceToken が生成されない可能性があります。プッシュトークンを無効にします。ただし、誰かがドアベルを鳴らすと、バックグラウンドはそれを有効な deviceToken として扱い、$deviceTokens に含めます。期限切れの deviceToken をクリアする方法は考慮する必要がある問題です。

関連情報を確認したところ、APNS サービスには

APNS リモート プッシュを実行するときに、ユーザーがアプリをアンインストールしたためにプッシュが失敗した場合、APNS サーバーは deviceToken を記録し、リストに追加して、データベースから期限切れのプッシュ トークンを取得できます。これらの期限切れのトークンにより、次回のプッシュ時にプッシュ配列にトークンが追加されなくなる可能性があります。このサービスへの接続は非常に簡単で、開発環境が

<span style="font-family: 宋体, SimSun; font-size: 18px;"></span>,テスト環境は <span style="font-family: 宋体, SimSun; font-size: 18px;">feedback.push.apple.com</span>フィードバック.sandbox.push.apple.comポートはすべて 2196 です。 APNS サーバーから返されるデータ形式は次のとおりです:

""

タイムスタンプ

アプリがデバイス上に存在しなくなったとAPNが判断した時期を示すタイムスタンプ(4バイトのtime_t値として)。 この値はネットワーク順であり、1970 年 1 月 1 日深夜 12:00 UTC からの秒数を表します。

トークンの長さ

ネットワーク順序での 2 バイトの整数値としてのデバイス トークンの長さ。

デバイストークン

バイナリ形式のデバイス トークン。

このサービスを実行するために、CIフレームワークコントローラーを作成しました

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Admin extends CI_Controller {
    public function __construct()
    {
        parent::__construct();
        // 加载数据库
        $this->load->database();
        $this->load->model('apns_model');
    }
    public function apnsfeedback()
    {
        $ctx = stream_context_create();
         $passphrase = 'xxxxx';
        stream_context_set_option($ctx, 'ssl', 'local_cert', 'xxxxxxx.pem');
        stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
        $fp = stream_socket_client('ssl://feedback.push.apple.com:2196', $error, $errorString, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
        if (!$fp) {
            echo "Failed to connect feedback server: $err $errstrn";
            return;
        }
        else {
            echo "Connection to feedback server OKn";
            echo "<br>";
        }
        while ($devcon = fread($fp, 38))
        {
            $arr = unpack("H*", $devc
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境