Scrittura e risposta a messaggi Pub/Sub

ID regione

REGION_ID è un codice abbreviato assegnato da Google in base alla regione selezionata al momento della creazione dell'app. Il codice non corrispondono a un paese o a una provincia, anche se potrebbero essere visualizzati alcuni ID regione in modo simile ai codici paese e provincia di uso comune. Per le app create dopo il giorno Febbraio 2020, REGION_ID.r è incluso in URL di App Engine. Per le app esistenti create prima di questa data, l'ID regione è facoltativo nell'URL.

Scopri di più sugli ID regione.

Pub/Sub fornisce una messaggistica asincrona many-to-many affidabile tra le applicazioni. Le applicazioni publisher possono inviare messaggi a un argomento e altre applicazioni possono abbonarsi all'argomento per riceverli.

Questo documento descrive come utilizzare le librerie client di Cloud per inviare e e ricevere messaggi Pub/Sub in un'app di App Engine. per inviare e ricevere messaggi Pub/Sub in un'app di App Engine per Java runtime versione 8 e versione 11/17. Tieni presente che devi aggiornare il file app.yaml per utilizzare la nuova versione. Consulta: Runtime Java per ulteriori informazioni sull'utilizzo dei nuovi runtime.

Prerequisiti

Clonazione dell'app di esempio

Copia le app di esempio sulla tua macchina locale e vai al pubsub directory:

Vai

git clone https://github.com/GoogleCloudPlatform/golang-samples.git
cd golang-samples/appengine_flexible/pubsub

Java

versione 11/17

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/java-11/pubsub/

versione 8

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/java-8/pubsub/

Node.js

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

PHP

git clone https://github.com/GoogleCloudPlatform/php-docs-samples.git
cd php-docs-samples/pubsub

Python

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

Ruby

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

.NET

git clone  https://github.com/GoogleCloudPlatform/dotnet-docs-samples
cd dotnet-docs-samples/appengine/flexible/Pubsub/Pubsub.Sample

Crea un argomento e una sottoscrizione

Crea un argomento e una sottoscrizione, che include la specifica dell'endpoint a cui deve inviare richieste il server Pub/Sub:

Vai

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

Sostituisci YOUR_TOKEN con un token casuale segreto. L'endpoint push utilizza questo per verificare le richieste.

Per utilizzare Pub/Sub con l'autenticazione, crea un altro abbonamento:

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your service agent
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

Sostituisci YOUR-SERVICE-ACCOUNT-EMAIL con l'indirizzo email del tuo account di servizio.

Java

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

Sostituisci YOUR_TOKEN con un token casuale segreto. L'endpoint push utilizza questo per verificare le richieste.

Per utilizzare Pub/Sub con l'autenticazione, crea un'altra sottoscrizione:

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your service agent
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

Sostituisci YOUR-SERVICE-ACCOUNT-EMAIL con l'indirizzo email del tuo account di servizio.

Node.js

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

Sostituisci YOUR_TOKEN con un token casuale segreto. L'endpoint push utilizza questo per verificare le richieste.

Per utilizzare Pub/Sub con l'autenticazione, crea un'altra sottoscrizione:

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your service agent
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

Sostituisci YOUR-SERVICE-ACCOUNT-EMAIL con l'indirizzo email del tuo account di servizio.

PHP

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

Sostituisci YOUR_TOKEN con un token segreto casuale. L'endpoint push lo utilizza per verificare le richieste.

Per utilizzare Pub/Sub con l'autenticazione, crea un altro abbonamento:

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your service agent
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

Sostituisci YOUR-SERVICE-ACCOUNT-EMAIL con l'indirizzo email del tuo account di servizio.

Python

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

Sostituisci YOUR_TOKEN con un token casuale segreto. L'endpoint push utilizza questo per verificare le richieste.

Per utilizzare Pub/Sub con l'autenticazione, crea un altro abbonamento:

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your service agent
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

Sostituisci YOUR-SERVICE-ACCOUNT-EMAIL con l'indirizzo email del tuo account di servizio.

Ruby

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

Sostituisci YOUR_TOKEN con un token casuale segreto. L'endpoint push lo utilizza per verificare le richieste.

Per utilizzare Pub/Sub con l'autenticazione, crea un altro abbonamento:

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your service agent
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

Sostituisci YOUR-SERVICE-ACCOUNT-EMAIL con l'indirizzo email del tuo account di servizio.

.NET

# Configure the topic
gcloud pubsub topics create YOUR_TOPIC_NAME

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

Sostituisci YOUR_TOKEN con un token segreto casuale. L'endpoint push utilizza questo per verificare le richieste.

Per utilizzare Pub/Sub con l'autenticazione, crea un altro abbonamento:

# Configure the push subscription
gcloud pubsub subscriptions create YOUR_SUBSCRIPTION_NAME \
    --topic=YOUR_TOPIC_NAME \
    --push-auth-service-account=YOUR-SERVICE-ACCOUNT-EMAIL\
    --push-auth-token-audience=OPTIONAL_AUDIENCE_OVERRIDE\
    --push-endpoint=https://YOUR_PROJECT_ID.REGION_ID.r.appspot.com/push-handlers/receive_messages?token=YOUR_TOKEN \
    --ack-deadline=10

# Your service agent
# `service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com` needs to have the
# `iam.serviceAccountTokenCreator` role.
PUBSUB_SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:${PUBSUB_SERVICE_ACCOUNT}"\
    --role='roles/iam.serviceAccountTokenCreator'

Sostituisci YOUR-SERVICE-ACCOUNT-EMAIL con l'indirizzo email del tuo account di servizio.

Imposta le variabili di ambiente

Vai

Modifica il file app.yaml per impostare le variabili di ambiente per l'argomento e token di verifica:

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

Java

Modifica il file app.yaml per impostare le variabili di ambiente per l'argomento e il token di verifica:

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

Node.js

Modifica il file app.yaml per impostare le variabili di ambiente per l'argomento e token di verifica:

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

PHP

Modifica il file index.php per impostare le variabili di ambiente per l'argomento e abbonamento:

$container->set('topic', 'php-example-topic');
$container->set('subscription', 'php-example-subscription');

Python

Modifica il file app.yaml per impostare le variabili di ambiente per l'ID progetto, l'argomento e il token di verifica:

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

Ruby

Modifica il file app.yaml per impostare le variabili di ambiente per l'ID progetto, l'argomento e il token di verifica:

env_variables:
    PUBSUB_TOPIC: <pubsub-topic-name>
    # This token is used to verify that requests originate from your
    # application. It can be any sufficiently random string.
    PUBSUB_VERIFICATION_TOKEN: <verification-token>

.NET

Modifica il file app.yaml per impostare le variabili di ambiente per l'argomento e il token di verifica:

runtime: aspnetcore
env: flex

runtime_config:
  operating_system: ubuntu22

env_variables:
  TEST_PROJECT_ID: your-project-id
  TEST_VERIFICATION_TOKEN: your-token
  TEST_TOPIC_ID: your-topic
  TEST_SUBSCRIPTION_ID: your-sub
  TEST_AUTH_SUBSCRIPTION_ID: your-auth-sub
  TEST_SERVICE_ACCOUNT_EMAIL: your-service-account-email

Revisione del codice

L'app di esempio utilizza la libreria client Pub/Sub.

Vai

L'app di esempio utilizza le variabili di ambiente che hai impostato nel file app.yaml (PUBSUB_TOPIC e PUBSUB_VERIFICATION_TOKEN) per la configurazione.

I messaggi ricevuti da questa istanza sono archiviati in una sezione:

messages   []string

La funzione pushHandler riceve i messaggi inviati tramite push, verifica il token e aggiunge il messaggio alla sezione 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:]
	}
}

La funzione publishHandler pubblica nuovi messaggi nell'argomento.


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.")
}

Java

L'app di esempio utilizza i valori impostati nel file app.yaml per configurare le variabili di ambiente. Il gestore delle richieste push utilizza questi valori per confermare che la richiesta provenga da Pub/Sub e abbia avuto origine da un fonte:

String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");

L'app di esempio gestisce un'istanza del database Cloud Datastore per archiviare i messaggi. Il servlet PubSubPush riceve i messaggi inviati tramite push e li aggiunge al Istanza di database messageRepository:

versione 11/17

@WebServlet(value = "/pubsub/push")
@MultipartConfig()
public class PubSubPush extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");
    // Do not process message if request token does not match pubsubVerificationToken
    if (pubsubVerificationToken == null
        || pubsubVerificationToken.compareTo(req.getParameter("token")) != 0) {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      return;
    }
    // parse message object from "message" field in the request body json
    // decode message data from base64
    Message message = getMessage(req);
    try {
      messageRepository.save(message);
      // 200, 201, 204, 102 status codes are interpreted as success by the Pub/Sub system
      resp.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
      System.out.println(e);
      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
  }

versione 8

@WebServlet(value = "/pubsub/push")
public class PubSubPush extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    String pubsubVerificationToken = System.getenv("PUBSUB_VERIFICATION_TOKEN");
    // Do not process message if request token does not match pubsubVerificationToken
    if (req.getParameter("token").compareTo(pubsubVerificationToken) != 0) {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      return;
    }
    // parse message object from "message" field in the request body json
    // decode message data from base64
    Message message = getMessage(req);
    try {
      messageRepository.save(message);
      // 200, 201, 204, 102 status codes are interpreted as success by the Pub/Sub system
      resp.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception e) {
      resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
  }

Il servlet PubSubPublish interagisce con l'app web App Engine per pubblicare nuovi messaggi e visualizzare quelli ricevuti:

@WebServlet(name = "Publish with PubSub", value = "/pubsub/publish")
public class PubSubPublish extends HttpServlet {

  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    Publisher publisher = this.publisher;
    try {
      String topicId = System.getenv("PUBSUB_TOPIC");
      // create a publisher on the topic
      if (publisher == null) {
        publisher = Publisher.newBuilder(
            ProjectTopicName.of(ServiceOptions.getDefaultProjectId(), topicId))
            .build();
      }
      // construct a pubsub message from the payload
      final String payload = req.getParameter("payload");
      PubsubMessage pubsubMessage =
          PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8(payload)).build();

      publisher.publish(pubsubMessage);
      // redirect to home page
      resp.sendRedirect("/");
    } catch (Exception e) {
      resp.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMessage());
    }
  }

Node.js

L'app di esempio utilizza i valori impostati nel file app.yaml per configurare le variabili di ambiente. Il gestore delle richieste push utilizza questi valori per confermare che la richiesta proviene da Pub/Sub e da una fonte attendibile:

// The following environment variables are set by the `app.yaml` file when
// running on App Engine, but will need to be manually set when running locally.
var PUBSUB_VERIFICATION_TOKEN = process.env.PUBSUB_VERIFICATION_TOKEN;
var pubsub = gcloud.pubsub({
    projectId: process.env.GOOGLE_CLOUD_PROJECT
});
var topic = pubsub.topic(process.env.PUBSUB_TOPIC);

L'app di esempio gestisce un elenco globale per archiviare i messaggi ricevuti da questa istanza:

// List of all messages received by this instance
var messages = [];

Questo metodo riceve i messaggi push e li aggiunge all'elenco globale messages:

app.post('/pubsub/push', jsonBodyParser, (req, res) => {
  if (req.query.token !== PUBSUB_VERIFICATION_TOKEN) {
    res.status(400).send();
    return;
  }

  // The message is a unicode string encoded in base64.
  const message = Buffer.from(req.body.message.data, 'base64').toString(
    'utf-8'
  );

  messages.push(message);

  res.status(200).send();
});

Questo metodo interagisce con l'app web App Engine per pubblicare nuovi per visualizzare i messaggi ricevuti:

app.get('/', (req, res) => {
  res.render('index', {messages, tokens, claims});
});

app.post('/', formBodyParser, async (req, res, next) => {
  if (!req.body.payload) {
    res.status(400).send('Missing payload');
    return;
  }

  const data = Buffer.from(req.body.payload);
  try {
    const messageId = await topic.publishMessage({data});
    res.status(200).send(`Message ${messageId} sent.`);
  } catch (error) {
    next(error);
  }
});

PHP

L'app di esempio utilizza i valori che hai impostato nel file app.yaml per configurare variabili di ambiente. Il gestore di richieste push utilizza questi valori per confermare che la richiesta provenisse da Pub/Sub e abbia avuto origine da un'origine attendibile:

runtime: php
env: flex

L'app di esempio gestisce un elenco globale per archiviare i messaggi ricevuti da questa istanza:

$messages = [];

Il metodo pull recupera i messaggi dall'argomento che hai creato e li aggiunge all'elenco dei messaggi:

// get PULL pubsub messages
$pubsub = new PubSubClient([
    'projectId' => $projectId,
]);
$subscription = $pubsub->subscription($subscriptionName);
$pullMessages = [];
foreach ($subscription->pull(['returnImmediately' => true]) as $pullMessage) {
    $pullMessages[] = $pullMessage;
    $messages[] = $pullMessage->data();
}
// acknowledge PULL messages
if ($pullMessages) {
    $subscription->acknowledgeBatch($pullMessages);
}

Il metodo publish pubblica nuovi messaggi nell'argomento:

if ($message = (string) $request->getBody()) {
    // Publish the pubsub message to the topic
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $topic = $pubsub->topic($topicName);
    $topic->publish(['data' => $message]);
    return $response->withStatus(204);
}

Python

L'app di esempio utilizza i valori che hai impostato nel file app.yaml per configurare variabili di ambiente. Il gestore delle richieste push utilizza questi valori per confermare che la richiesta proviene da Pub/Sub e da una fonte attendibile:

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

L'app di esempio gestisce un elenco globale per archiviare i messaggi ricevuti da questa istanza:

MESSAGES = []

Il metodo pubsub_push() riceve i messaggi inviati tramite push e li aggiunge a MESSAGES elenco globale:

@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

Il metodo index() interagisce con l'app web App Engine per la pubblicazione nuovi messaggi e visualizzazione dei messaggi ricevuti:

@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

Ruby

L'app di esempio utilizza i valori impostati nel file app.yaml per configurare le variabili di ambiente. Il gestore delle richieste push utilizza questi valori per confermare che la richiesta proviene da Pub/Sub e da una fonte attendibile:

topic = pubsub.topic ENV["PUBSUB_TOPIC"]
PUBSUB_VERIFICATION_TOKEN = ENV["PUBSUB_VERIFICATION_TOKEN"]

L'app di esempio gestisce un elenco globale per archiviare i messaggi ricevuti da questa istanza:

# List of all messages received by this instance
messages = []

Questo metodo riceve i messaggi push e li aggiunge all'elenco globale messages:

post "/pubsub/push" do
  halt 400 if params[:token] != PUBSUB_VERIFICATION_TOKEN

  message = JSON.parse request.body.read
  payload = Base64.decode64 message["message"]["data"]

  messages.push payload
end

Questo metodo interagisce con l'app web App Engine per pubblicare nuovi messaggi e visualizzare quelli ricevuti:

get "/" do
  @claims = claims
  @messages = messages

  slim :index
end

post "/publish" do
  topic.publish params[:payload]

  redirect "/", 303
end

.NET

[HttpGet]
[HttpPost]
public async Task<IActionResult> IndexAsync(MessageForm messageForm)
{
    var model = new MessageList();
    if (!_options.HasGoodProjectId())
    {
        model.MissingProjectId = true;
        return View(model);
    }
    if (!string.IsNullOrEmpty(messageForm.Message))
    {
        // Publish the message.
        var pubsubMessage = new PubsubMessage()
        {
            Data = ByteString.CopyFromUtf8(messageForm.Message)
        };
        pubsubMessage.Attributes["token"] = _options.VerificationToken;
        await _publisher.PublishAsync(pubsubMessage);
        model.PublishedMessage = messageForm.Message;
    }
    // Render the current list of messages.
    model.Messages = s_receivedMessages.ToArray();
    model.AuthMessages = s_authenticatedMessages.ToArray();
    return View(model);
}

Esecuzione dell'esempio in locale

Quando esegui l'app localmente, puoi utilizzare Google Cloud CLI per fornire l'autenticazione per l'utilizzo delle API Google Cloud. Supponendo di aver configurato l'ambiente come descritto in Prerequisiti, hai già eseguito il comando gcloud init che fornisce questa autenticazione.

Vai

Imposta le variabili di ambiente prima di avviare l'applicazione:

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

Java

mvn clean package

Imposta le variabili di ambiente prima di avviare l'applicazione:

export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
mvn jetty:run

Node.js

Imposta le variabili di ambiente prima di avviare l'applicazione:

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
npm install
npm start

PHP

Installa le dipendenze utilizzando Composer:

composer install

Quindi imposta le variabili di ambiente prima di avviare l'applicazione:

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
php -S localhost:8080

Python

Installa le dipendenze, preferibilmente in un ambiente virtuale.

Mac OS / Linux

  1. Crea un ambiente Python isolato:
    python3 -m venv env
    source env/bin/activate
  2. Se non ti trovi nella directory che contiene il codice campione, vai alla directory che contiene il codice campione hello_world. Quindi installa dependencies:
    cd YOUR_SAMPLE_CODE_DIR
    pip install -r requirements.txt

Windows

Utilizza PowerShell per eseguire i pacchetti Python.

  1. Individua la tua installazione di PowerShell.
  2. Fai clic con il tasto destro del mouse sulla scorciatoia a PowerShell e avviala come amministratore.
  3. Crea un ambiente Python isolato.
    python -m venv env
    .\env\Scripts\activate
  4. Naviga alla directory del progetto e installa le dipendenze. Se non sei nella directory che contiene il codice campione, passa alla directory che contiene Codice campione hello_world. Quindi, installa le dipendenze:
    cd YOUR_SAMPLE_CODE_DIR
    pip install -r requirements.txt

Quindi imposta le variabili di ambiente prima di avviare l'applicazione:

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

Ruby

Installa le dipendenze:

bundle install

Quindi imposta le variabili di ambiente prima di avviare l'applicazione:

export GOOGLE_CLOUD_PROJECT=[your-project-id]
export PUBSUB_VERIFICATION_TOKEN=[your-verification-token]
export PUBSUB_TOPIC=[your-topic]
bundle exec ruby app.rb -p 8080

.NET

Esegui i comandi seguenti dalla directory radice dell'applicazione:

    dotnet restore
    dotnet run

Nel tuo browser web, inserisci http://localhost:5000/. Per uscire dal server web, premi Ctrl+C nella finestra del terminale.

Simulazione di notifiche push

L'applicazione può inviare messaggi localmente, ma non è in grado di ricevere messaggi push in locale. Tuttavia, puoi simulare un messaggio push inviando una richiesta HTTP all'endpoint di notifica push locale. L'esempio include il file sample_message.json.

Vai

Puoi utilizzare curl o un client httpie per inviare una richiesta HTTP POST:

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

Oppure

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

Risposta:

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

Una volta completata la richiesta, puoi aggiornare localhost:8080 e visualizzare messaggio nell'elenco dei messaggi ricevuti.

Java

Puoi usare curl o un cliente httpie per invia una richiesta POST HTTP:

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

Oppure

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

Risposta:

HTTP/1.1 200 OK
Date: Wed, 26 Apr 2017 00:03:28 GMT
Content-Length: 0
Server: Jetty(9.3.8.v20160314)

Al termine della richiesta, puoi aggiornare localhost:8080 e visualizzare il messaggio nell'elenco dei messaggi ricevuti.

Node.js

Puoi usare curl o un cliente httpie per invia una richiesta POST HTTP:

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

Oppure

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

Risposta:

HTTP/1.1 200 OK
Connection: keep-alive
Date: Mon, 31 Aug 2015 22:19:50 GMT
Transfer-Encoding: chunked
X-Powered-By: Express

Una volta completata la richiesta, puoi aggiornare localhost:8080 e visualizzare messaggio nell'elenco dei messaggi ricevuti.

PHP

Puoi utilizzare curl o un client httpie per inviare una richiesta HTTP POST:

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

Oppure

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

Al termine della richiesta, puoi aggiornare localhost:8080 e visualizzare il messaggio nell'elenco dei messaggi ricevuti.

Python

Puoi usare curl o un cliente httpie per invia una richiesta POST HTTP:

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

Oppure

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

Risposta:

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

Una volta completata la richiesta, puoi aggiornare localhost:8080 e visualizzare messaggio nell'elenco dei messaggi ricevuti.

Ruby

Puoi usare curl o un cliente httpie per invia una richiesta POST HTTP:

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

Oppure

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

Risposta:

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Content-Length: 13
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Server: WEBrick/1.3.1 (Ruby/2.3.0/2015-12-25)
Date: Wed, 20 Apr 2016 20:56:23 GMT
Connection: Keep-Alive

Hello, World!

Al termine della richiesta, puoi aggiornare localhost:8080 e visualizzare il messaggio nell'elenco dei messaggi ricevuti.

.NET

Per inviare una richiesta HTTP POST:

Get-Content -Raw .\sample_message.json | Invoke-WebRequest -Uri
http://localhost:5000/Push?token=your-secret-token -Method POST -ContentType
'text/json' -OutFile out.txt

Una volta completata la richiesta, puoi aggiornare localhost:5000 e visualizzare messaggio nell'elenco dei messaggi ricevuti.

Esecuzione su App Engine

Per eseguire il deployment dell'app di demo in App Engine utilizzando lo strumento gcloud a riga di comando:

Vai

Esegui il comando seguente dalla directory in cui si trova il file app.yaml:

gcloud app deploy

Java

Per eseguire il deployment della tua app utilizzando Maven, esegui questo comando:

mvn package appengine:deploy -Dapp.deploy.projectId=PROJECT_ID

Sostituisci PROJECT_ID con l'ID del tuo progetto Google Cloud. Se il tuo file pom.xml specifica già il tuo ID progetto, non devi includere la proprietà -Dapp.deploy.projectId nel comando eseguito.

Node.js

Esegui il comando seguente dalla directory in cui si trova il file app.yaml:

gcloud app deploy

PHP

Esegui questo comando dalla directory in cui si trova il file app.yaml:

gcloud app deploy

Python

Esegui il comando seguente dalla directory in cui si trova il file app.yaml:

gcloud app deploy

Ruby

Esegui questo comando dalla directory in cui si trova il file app.yaml:

gcloud app deploy app.yaml

.NET

Esegui questo comando dalla directory in cui si trova il file app.yaml:

gcloud app deploy

Ora puoi accedere all'applicazione da https://PROJECT_ID.REGION_ID.r.appspot.com. Puoi utilizzare il modulo per inviare messaggi, ma non è garantito quale istanza della tua applicazione riceverà la notifica. Puoi inviare più messaggi e aggiornare la pagina per visualizzare il messaggio ricevuto.