0

リアルタイム サブスクリプションを作成すると、異なる Instagram IP アドレスから重複した通知を受け取るという問題があります。通知を受け取ったら、min_tag_id 設定を使用して最新の更新のリクエストを送信するように設定しました。それをデータベースに保存して、次のリクエストに使用します。私は常に重複を取得するとは限りませんが、重複を取得すると、通知に関するすべてが同じ (時間、オブジェクト、changed_aspect) になりますが、2 つのほぼ同一の要求をリストするデバッグ出力とは異なることがわかります...異なる情報は異なる IP アドレスであり、REQUEST_TIME_FLOAT は約 1/10 秒異なります。HTTP_X_HUB_SIGNATURE 値も同じです。

私の一般的なアルゴリズムは次のとおりです。

process_subscription_update($data){
    # get old min_id
    $min_tag_id = mysqli_fetch_object(mysqli_query($dbconnecti,sprintf("SELECT instagram_min_id+0 as instaid FROM xxxx WHERE xxxx=%d",$_GET['xxxx'])));
    $min_id = $min_tag_id->instaid;
    # make api call
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL, 'https://api.instagram.com/v1/tags/'.$_GET['tag'].'/media/recent?client_id=xxxx&min_tag_id='.$min_id.($min_id==0?'&count=1':''));
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    $result = curl_exec($ch);
    curl_close($ch);
    $i = json_decode($result);
    if ($min_id == $i->pagination->min_tag_id) { exit; }
    # write new min_id to db
    record_min_id($i->pagination->min_tag_id);
    $data2 = $i->data;
    foreach($data2 as $d) {
        process_instagram($d);
    }
    // debugging output: ****************
    $file = file_get_contents($_SERVER['DOCUMENT_ROOT'].'instagram/updates.txt');
    $foo = "\n";
    foreach($_SERVER as $key_name => $key_value) {
        $foo .= $key_name . " = " . $key_value . "\n";
    }
    $fulldata = $file . "\n\n\n" .  $result . "\n min_id = " . $min_id . $foo;
    $fulldata .= "\nTIME:".$data[0]->time;
    $fulldata .= "\nOBJECT:".$data[0]->object;
    $fulldata .= "\nCHANGED_ASPECT:".$data[0]->changed_aspect;
    file_put_contents($_SERVER['DOCUMENT_ROOT'].'instagram/updates.txt', $fulldata);    
    // end debugging output *************

}

Instagram メッセージ ID が process_instagram 関数内のデータベースに既に存在するかどうかを確認したくないのですが、重複が 1/10 秒しか離れていないため、それが機能するかどうかはわかりません。

他の誰かがこれを経験したり、解決策を持っていますか?

4

1 に答える 1

0

私はこれを解決しました。重複した通知を受け取ることについて、私にできることは何もないと思います。したがって、Instagram をデータベースに書き込むときは、Instagram ID 用のフィールドがあり、そのフィールドに一意の制約を設定します。mysqli INSERT を実行した後、errno = 1062 かどうかを確認し、そうであれば終了します。

mysqli_query($dbconnecti,"INSERT INTO xxx (foo, etc, instagram_id ...")
if ($dbconnecti->errno==1062) { exit; }
...
// more script runs here if we don't have a duplicate.
于 2015-01-19T19:28:28.210 に答える