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

リージョン ID

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

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

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

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

前提事項

  • App Engine の Go 用 Hello, World! の説明に従って環境とプロジェクトをセットアップし、App Engine での Go アプリの構造を理解してください。
  • このドキュメントで説明しているサンプル アプリケーションを実行する際に必要となるため、プロジェクト ID を書き留めておきます。

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

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

    go get -d -v github.com/GoogleCloudPlatform/golang-samples/pubsub
    cd $GOPATH/src/github.com/GoogleCloudPlatform/golang-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 ファイルを編集して、トピックと検証トークンの各環境変数を設定します。

    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: your-token

    コードレビュー

    このサンプルアプリでは、Google Cloud Pub/Sub クライアント ライブラリを使用しています。

    このサンプルアプリでは、構成用として app.yaml ファイルに設定された環境変数(PUBSUB_TOPICPUBSUB_VERIFICATION_TOKEN)を使用します。

    このインスタンスが受信したメッセージがスライスに格納されます。

    messages   []string
    

    pushHandler 関数は、push されたメッセージを受信してトークンを検証し、メッセージを messages スライスに追加します。

    
    func pushHandler(w http.ResponseWriter, r *http.Request) {
    	// Verify the token.
    	if r.URL.Query().Get("token") != token {
    		http.Error(w, "Bad token", http.StatusBadRequest)
    		return
    	}
    	msg := &pushRequest{}
    	if err := json.NewDecoder(r.Body).Decode(msg); err != nil {
    		http.Error(w, fmt.Sprintf("Could not decode body: %v", err), http.StatusBadRequest)
    		return
    	}
    
    	messagesMu.Lock()
    	defer messagesMu.Unlock()
    	// Limit to ten.
    	messages = append(messages, string(msg.Message.Data))
    	if len(messages) > maxMessages {
    		messages = messages[len(messages)-maxMessages:]
    	}
    }

    publishHandler 関数は、新しいメッセージをトピックに公開します。

    
    func publishHandler(w http.ResponseWriter, r *http.Request) {
    	ctx := context.Background()
    
    	msg := &pubsub.Message{
    		Data: []byte(r.FormValue("payload")),
    	}
    
    	if _, err := topic.Publish(ctx, msg).Get(ctx); err != nil {
    		http.Error(w, fmt.Sprintf("Could not publish message: %v", err), 500)
    		return
    	}
    
    	fmt.Fprint(w, "Message published.")
    }

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

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

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

    export GOOGLE_CLOUD_PROJECT=[your-project-id]
    export PUBSUB_VERIFICATION_TOKEN=[your-token]
    export PUBSUB_TOPIC=[your-topic]
    go run pubsub.go
    

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

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

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

    curl -H "Content-Type: application/json" -i --data @sample_message.json "localhost:8080/pubsub/push?token=[your-token]"
    

    または

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

    レスポンス:

    HTTP/1.1 200 OK
    Date: Tue, 13 Nov 2018 16:04:18 GMT
    Content-Length: 0
    

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

    App Engine 上で実行する

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

    gcloud app deploy
    

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