Pub/Sub メッセージの作成とレスポンス

リージョン ID

REGION_ID は、アプリの作成時に選択したリージョンに基づいて Google が割り当てる省略形のコードです。一部のリージョン ID は、一般的に使用されている国や州のコードと類似しているように見える場合がありますが、このコードは国または州に対応するものではありません。2020 年 2 月以降に作成されたアプリの場合、REGION_ID.r が App Engine の URL に含まれています。この日付より前に作成されたアプリの場合、URL のリージョン ID は省略可能です。

詳しくは、リージョン ID をご覧ください。

Pub/Sub は、信頼できる多対多の非同期メッセージングをアプリケーション間で行います。パブリッシャー アプリケーションはメッセージをトピックに送信し、その他のアプリケーションはそのトピックにサブスクライブしてメッセージを受信できます。

このドキュメントでは、Cloud クライアント ライブラリを使用して、Python アプリで Pub/Sub メッセージを送受信する方法を説明します。

前提事項

  • App Engine の Python 用「Hello, World!」の説明に沿って環境とプロジェクトを設定し、App Engine の Python アプリの構造について理解します。
  • このドキュメントで説明しているサンプルアプリを実行する際に必要となるため、プロジェクト ID を書き留めておきます。

    サンプルアプリのクローン作成

    サンプルアプリをローカルマシンにコピーし、pubsub ディレクトリに移動します。

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples
    cd python-docs-samples/appengine/flexible/pubsub
    

    トピックとサブスクリプションの作成

    トピックとサブスクリプションを作成します。Pub/Sub サーバーがリクエストを送信するエンドポイントも指定します。

    gcloud pubsub topics create YOUR_TOPIC_NAME
    gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
        --topic YOUR_TOPIC_NAME \
        --push-endpoint \
        https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/pubsub/push?token=YOUR_TOKEN \
        --ack-deadline 10
    

    YOUR_TOKEN は、ランダムなシークレット トークンで置き換えます。push エンドポイントがこれを使用してリクエストを検証します。

    環境変数の設定

    app.yaml を編集して、プロジェクト ID、トピック、検証トークンの各環境変数を設定します。

    env_variables:
        PUBSUB_TOPIC: your-topic
        # This token is used to verify that requests originate from your
        # application. It can be any sufficiently random string.
        PUBSUB_VERIFICATION_TOKEN: 1234abc

    コードレビュー

    サンプルアプリでは、Cloud Client ライブラリを使用しています。

    このサンプルアプリでは、app.yaml ファイルに設定された値を使用して環境変数を構成します。push リクエスト ハンドラは、これらの値を使用して、Pub/Sub からのリクエストで、信頼できる送信元から送信されていることを確認します。

    app.config['PUBSUB_VERIFICATION_TOKEN'] = \
        os.environ['PUBSUB_VERIFICATION_TOKEN']
    app.config['PUBSUB_TOPIC'] = os.environ['PUBSUB_TOPIC']
    

    このサンプルアプリは、このインスタンスで受信したメッセージをグローバル リストに保存します。

    MESSAGES = []
    
    pubsub_push() メソッドは、push されたメッセージを受信し、MESSAGES グローバル リストに追加します。

    @app.route('/pubsub/push', methods=['POST'])
    def pubsub_push():
        if (request.args.get('token', '') !=
                current_app.config['PUBSUB_VERIFICATION_TOKEN']):
            return 'Invalid request', 400
    
        envelope = json.loads(request.data.decode('utf-8'))
        payload = base64.b64decode(envelope['message']['data'])
    
        MESSAGES.append(payload)
    
        # Returning any 2xx status indicates successful receipt of the message.
        return 'OK', 200

    index() メソッドは、App Engine ウェブアプリと連携して新しいメッセージを公開し、受信したメッセージを表示します。

    @app.route('/', methods=['GET', 'POST'])
    def index():
        if request.method == 'GET':
            return render_template('index.html', messages=MESSAGES)
    
        data = request.form.get('payload', 'Example payload').encode('utf-8')
    
        # publisher = pubsub_v1.PublisherClient()
        topic_path = publisher.topic_path(
            current_app.config['PROJECT'],
            current_app.config['PUBSUB_TOPIC'])
    
        publisher.publish(topic_path, data=data)
    
        return 'OK', 200

    サンプルのローカルでの実行

    ローカルで実行する場合、Google Cloud APIs を使用するための認証を行うには、Cloud SDK を利用します。前提条件に記載されているとおりに環境を設定していれば、この認証を行う gcloud init コマンドはすでに実行されています。

    可能であれば、依存関係を仮想環境にインストールします。

    Mac OS / Linux

    1. 分離された Python 環境を作成します。
      python3 -m venv env
      source env/bin/activate
    2. 現在のディレクトリにサンプルコードが含まれていない場合は、hello_world サンプルコードが含まれるディレクトリに移動します。その後、依存関係をインストールします。
      cd YOUR_SAMPLE_CODE_DIR
      pip install -r requirements.txt

    Windows

    PowerShell を使用して Python パッケージを実行します。

    1. インストールされた PowerShell を探します。
    2. PowerShell へのショートカットを右クリックし、管理者として PowerShell を起動します。
    3. 分離された Python 環境を作成します。
      python -m venv env
      .\env\Scripts\activate
    4. プロジェクト ディレクトリに移動し、依存関係をインストールします。現在のディレクトリにサンプルコードが含まれていない場合は、hello_world サンプルコードが含まれるディレクトリに移動します。それから依存関係をインストールします。
      cd YOUR_SAMPLE_CODE_DIR
      pip install -r requirements.txt

    次に、アプリケーションを起動する前に環境変数を設定します。

    export GOOGLE_CLOUD_PROJECT=[your-project-id]
    export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
    export PUBSUB_TOPIC=[your-topic]
    python main.py
    

    プッシュ通知のシミュレート

    アプリケーションは、ローカルでメッセージを送信できますが、push メッセージを受信することはできません。push メッセージをシミュレートするには、ローカルのプッシュ通知エンドポイントに HTTP リクエストを送信します。このサンプルには、sample_message.json というファイルが含まれています。

    curl または httpie クライアントを使用して、HTTP POST リクエストを送信できます。

    curl -i --data @sample_message.json "localhost:8080/push-handlers/receive_messages?token=[your-token]"
    

    または

    http POST ":8080/push-handlers/receive_messages?token=[your-token]" < sample_message.json
    

    レスポンス:

    HTTP/1.0 200 OK
    Content-Length: 2
    Content-Type: text/html; charset=utf-8
    Date: Mon, 10 Aug 2015 17:52:03 GMT
    Server: Werkzeug/0.10.4 Python/2.7.10
    
    OK
    

    リクエストの完了後、localhost:8080 を更新すると、受信メッセージのリストにメッセージが表示されます。

    App Engine 上で実行する

    gcloud コマンドライン ツールを使用してデモアプリを App Engine にデプロイするには、app.yaml ファイルが配置されているディレクトリから次のコマンドを実行します。

    gcloud app deploy
    

    これで、https://PROJECT_ID.REGION_ID.r.appspot.com のアプリケーションにアクセスできます。フォームを使用してメッセージを送信できますが、アプリケーションのどのインスタンスが通知を受信するかはわかりません。複数のメッセージを送信してページを更新すると、受信メッセージを確認できます。