כתיבה של הודעות ב-Pub/Sub ומענה להודעות

מזהה אזור

REGION_ID הוא קוד מקוצר ש-Google מקצה על סמך האזור שבוחרים כשיוצרים את האפליקציה. הקוד לא תואם למדינה או למחוז, למרות שחלק ממזהי האזורים עשויים להיראות דומים לקודים נפוצים של מדינות ומחוזות. באפליקציות שנוצרו אחרי פברואר 2020, המחרוזת REGION_ID.r כלולה בכתובות ה-URL של App Engine. באפליקציות קיימות שנוצרו לפני התאריך הזה, מזהה האזור הוא אופציונלי בכתובת ה-URL.

מידע נוסף על מזהי אזורים

Pub/Sub מספק העברת הודעות אסינכרונית בין אפליקציות, באופן אמין ורב-אל-רב. אפליקציות של מפרסמים יכולות לשלוח הודעות לנושא, ואפליקציות אחרות יכולות להירשם לנושא הזה כדי לקבל את ההודעות.

במאמר הזה נסביר איך להשתמש בספריות לקוח ב-Cloud כדי לשלוח ולקבל הודעות Pub/Sub באפליקציית App Engine. כדי להשתמש באפליקציה לדוגמה במדריך הזה עם כל גרסה נתמכת של Python, צריך לציין את גרסת זמן הריצה ואת מערכת ההפעלה בקובץ app.yaml.

דרישות מוקדמות

שיבוט של האפליקציה לדוגמה

מעתיקים את האפליקציות לדוגמה למחשב המקומי ועוברים אל הספרייה pubsub:

המשך

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

Java

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/java-11/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

יצירת נושא ומינוי

יוצרים נושא ומינוי, כולל ציון נקודת הקצה שאליה שרת Pub/Sub צריך לשלוח בקשות:

המשך

# 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

מחליפים את YOUR_TOKEN באסימון סודי אקראי. נקודת הקצה של ה-push משתמשת בזה כדי לאמת בקשות.

כדי להשתמש ב-Pub/Sub עם אימות, צריך ליצור מינוי נוסף:

# 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'

מחליפים את YOUR-SERVICE-ACCOUNT-EMAIL בכתובת האימייל של חשבון השירות.

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

מחליפים את YOUR_TOKEN באסימון סודי אקראי. נקודת הקצה של ה-push משתמשת בזה כדי לאמת בקשות.

כדי להשתמש ב-Pub/Sub עם אימות, צריך ליצור מינוי נוסף:

# 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'

מחליפים את YOUR-SERVICE-ACCOUNT-EMAIL בכתובת האימייל של חשבון השירות.

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

מחליפים את YOUR_TOKEN באסימון סודי אקראי. נקודת הקצה של ה-push משתמשת בזה כדי לאמת בקשות.

כדי להשתמש ב-Pub/Sub עם אימות, צריך ליצור מינוי נוסף:

# 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'

מחליפים את YOUR-SERVICE-ACCOUNT-EMAIL בכתובת האימייל של חשבון השירות.

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

מחליפים את YOUR_TOKEN באסימון סודי אקראי. נקודת הקצה של ה-push משתמשת בזה כדי לאמת בקשות.

כדי להשתמש ב-Pub/Sub עם אימות, צריך ליצור מינוי נוסף:

# 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'

מחליפים את YOUR-SERVICE-ACCOUNT-EMAIL בכתובת האימייל של חשבון השירות.

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

מחליפים את YOUR_TOKEN באסימון סודי אקראי. נקודת הקצה של ה-push משתמשת בזה כדי לאמת בקשות.

כדי להשתמש ב-Pub/Sub עם אימות, צריך ליצור מינוי נוסף:

# 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'

מחליפים את YOUR-SERVICE-ACCOUNT-EMAIL בכתובת האימייל של חשבון השירות.

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

מחליפים את YOUR_TOKEN באסימון סודי אקראי. נקודת הקצה של ה-push משתמשת בזה כדי לאמת בקשות.

כדי להשתמש ב-Pub/Sub עם אימות, צריך ליצור מינוי נוסף:

# 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'

מחליפים את YOUR-SERVICE-ACCOUNT-EMAIL בכתובת האימייל של חשבון השירות.

‎.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

מחליפים את YOUR_TOKEN באסימון סודי אקראי. נקודת הקצה של ה-push משתמשת בזה כדי לאמת בקשות.

כדי להשתמש ב-Pub/Sub עם אימות, צריך ליצור מינוי נוסף:

# 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'

מחליפים את YOUR-SERVICE-ACCOUNT-EMAIL בכתובת האימייל של חשבון השירות.

הגדרת משתני סביבה

המשך

עורכים את הקובץ 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

Java

עורכים את הקובץ app.yaml כדי להגדיר את משתני הסביבה לנושא ולטוקן לאימות בעלות:

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

עורכים את הקובץ app.yaml כדי להגדיר את משתני הסביבה של הנושא ואת טוקן לאימות בעלות:

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

עורכים את הקובץ index.php כדי להגדיר את משתני הסביבה לנושא ולמינוי:

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

Python

עורכים את הקובץ 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: 1234abc

Ruby

עורכים את הקובץ app.yaml כדי להגדיר את משתני הסביבה של מזהה הפרויקט, הנושא וטוקן לאימות בעלות:

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

עורכים את הקובץ app.yaml כדי להגדיר את משתני הסביבה של הנושא ואת טוקן לאימות בעלות:

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

סקר קוד

אפליקציית הדוגמה משתמשת בספריית הלקוח של Pub/Sub.

המשך

אפליקציית הדוגמה משתמשת במשתני הסביבה שהגדרתם בקובץ app.yaml (PUBSUB_TOPIC ו-PUBSUB_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.")
}

Java

אפליקציית הדוגמה משתמשת בערכים שהגדרתם בקובץ app.yaml כדי להגדיר משתני סביבה. ה-handler של בקשת ה-push משתמש בערכים האלה כדי לוודא שהבקשה הגיעה מ-Pub/Sub וממקור מהימן:

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

אפליקציית הדוגמה שומרת הודעות במופע של מסד נתונים ב-Cloud Datastore. ה-servlet‏ PubSubPush מקבל הודעות שנשלחו בדחיפה ומוסיף אותן למופע של מסד הנתונים messageRepository:

גרסה 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);
    }
  }

גרסה 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);
    }
  }

PubSubPublish servlet מתקשר עם אפליקציית האינטרנט של App Engine כדי לפרסם הודעות חדשות ולהציג הודעות שהתקבלו:

@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

אפליקציית הדוגמה משתמשת בערכים שהגדרתם בקובץ app.yaml כדי להגדיר משתני סביבה. ה-handler של בקשת ה-push משתמש בערכים האלה כדי לוודא שהבקשה הגיעה מ-Pub/Sub וממקור מהימן:

// 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);

אפליקציית הדוגמה שומרת רשימה גלובלית לאחסון הודעות שהתקבלו על ידי המופע הזה:

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

בשיטה הזו מתקבלות הודעות שנשלחות בשיטת Push והן מתווספות ל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();
});

השיטה הזו מתקשרת עם אפליקציית האינטרנט של App Engine כדי לפרסם הודעות חדשות ולהציג הודעות שהתקבלו:

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

אפליקציית הדוגמה משתמשת בערכים שהגדרתם בקובץ app.yaml כדי להגדיר משתני סביבה. ה-handler של בקשת ה-push משתמש בערכים האלה כדי לוודא שהבקשה הגיעה מ-Pub/Sub וממקור מהימן:

runtime: php
env: flex

אפליקציית הדוגמה שומרת רשימה גלובלית לאחסון הודעות שהתקבלו על ידי המופע הזה:

$messages = [];

השיטה pull מאחזרת הודעות מהנושא שיצרתם ומוסיפה אותן לרשימת ההודעות:

// 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);
}

השיטה publish מפרסמת הודעות חדשות בנושא:

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

אפליקציית הדוגמה משתמשת בערכים שהגדרתם בקובץ app.yaml כדי להגדיר משתני סביבה. ה-handler של בקשת ה-push משתמש בערכים האלה כדי לוודא שהבקשה הגיעה מ-Pub/Sub וממקור מהימן:

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

אפליקציית הדוגמה שומרת רשימה גלובלית לאחסון הודעות שהתקבלו על ידי המופע הזה:

MESSAGES = []

בשיטה pubsub_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

Ruby

אפליקציית הדוגמה משתמשת בערכים שהגדרתם בקובץ app.yaml כדי להגדיר משתני סביבה. ה-handler של בקשת ה-push משתמש בערכים האלה כדי לוודא שהבקשה הגיעה מ-Pub/Sub וממקור מהימן:

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

אפליקציית הדוגמה שומרת רשימה גלובלית לאחסון הודעות שהתקבלו על ידי המופע הזה:

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

בשיטה הזו מתקבלות הודעות שנשלחות בשיטת Push והן מתווספות ל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

השיטה הזו מתקשרת עם אפליקציית האינטרנט של App Engine כדי לפרסם הודעות חדשות ולהציג הודעות שהתקבלו:

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

  slim :index
end

post "/publish" do
  publisher.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);
}

הרצת הדוגמה באופן מקומי

כשמריצים באופן מקומי, אפשר להשתמש ב-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

Java

mvn clean package

מגדירים משתני סביבה לפני שמפעילים את האפליקציה:

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

Node.js

מגדירים משתני סביבה לפני שמפעילים את האפליקציה:

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

PHP

מתקינים את יחסי התלות באמצעות Composer:

composer install

לאחר מכן מגדירים משתני סביבה לפני שמפעילים את האפליקציה:

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

Python

מתקינים יחסי תלות, רצוי בסביבה וירטואלית.

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 ומפעילים אותו כאדמין.
  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

Ruby

יחסי תלות של התקנות:

bundle install

לאחר מכן מגדירים משתני סביבה לפני שמפעילים את האפליקציה:

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

מריצים את הפקודות הבאות מהספרייה הבסיסית של האפליקציה:

    dotnet restore
    dotnet run

בדפדפן האינטרנט, מקלידים http://localhost:5000/. כדי לצאת משרת האינטרנט, מקישים על Ctrl+C בחלון הטרמינל.

הדמיה של התראות

האפליקציה יכולה לשלוח הודעות באופן מקומי, אבל היא לא יכולה לקבל הודעות פוש באופן מקומי. עם זאת, אפשר לדמות הודעת פוש על ידי שליחת בקשת HTTP לנקודת הקצה (endpoint) של התראות הפוש המקומיות. הדוגמה כוללת את הקובץ sample_message.json.

המשך

אפשר להשתמש ב-curl או בלקוח httpie כדי לשלוח בקשת HTTP POST:

curl -H "Content-Type: application/json" -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.1 200 OK
Date: Tue, 13 Nov 2018 16:04:18 GMT
Content-Length: 0

אחרי שהבקשה תושלם, תוכלו לרענן את localhost:8080 ולראות את ההודעה ברשימת ההודעות שהתקבלו.

Java

אפשר להשתמש ב-curl או בלקוח httpie כדי לשלוח בקשת HTTP POST:

curl -H "Content-Type: application/json" -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.1 200 OK
Date: Wed, 26 Apr 2017 00:03:28 GMT
Content-Length: 0
Server: Jetty(9.3.8.v20160314)

אחרי שהבקשה תושלם, תוכלו לרענן את localhost:8080 ולראות את ההודעה ברשימת ההודעות שהתקבלו.

Node.js

אפשר להשתמש ב-curl או בלקוח httpie כדי לשלוח בקשת HTTP POST:

curl -H "Content-Type: application/json" -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.1 200 OK
Connection: keep-alive
Date: Mon, 31 Aug 2015 22:19:50 GMT
Transfer-Encoding: chunked
X-Powered-By: Express

אחרי שהבקשה תושלם, תוכלו לרענן את localhost:8080 ולראות את ההודעה ברשימת ההודעות שהתקבלו.

PHP

אפשר להשתמש ב-curl או בלקוח httpie כדי לשלוח בקשת HTTP POST:

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

או

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

אחרי שהבקשה תושלם, תוכלו לרענן את localhost:8080 ולראות את ההודעה ברשימת ההודעות שהתקבלו.

Python

אפשר להשתמש ב-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.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 ולראות את ההודעה ברשימת ההודעות שהתקבלו.

Ruby

אפשר להשתמש ב-curl או בלקוח httpie כדי לשלוח בקשת HTTP POST:

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

או

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

תשובה:

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!

אחרי שהבקשה תושלם, תוכלו לרענן את localhost:8080 ולראות את ההודעה ברשימת ההודעות שהתקבלו.

‎.NET

כדי לשלוח בקשת 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

אחרי שהבקשה תושלם, תוכלו לרענן את localhost:5000 ולראות את ההודעה ברשימת ההודעות שהתקבלו.

פועל ב-App Engine

כדי לפרוס את אפליקציית ההדגמה ב-App Engine באמצעות כלי שורת הפקודה gcloud:

המשך

מריצים את הפקודה הבאה מהספרייה שבה נמצא הקובץ app.yaml:

gcloud app deploy

Java

כדי לפרוס את האפליקציה באמצעות Maven, מריצים את הפקודה הבאה:

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

מחליפים את PROJECT_ID במזהה הפרויקט. Google Cloud אם קובץ pom.xml שלכם כבר מציין את מזהה הפרויקט, אין צורך לכלול את המאפיין -Dapp.deploy.projectId בפקודה שמריצים.

Node.js

מריצים את הפקודה הבאה מהספרייה שבה נמצא הקובץ app.yaml:

gcloud app deploy

PHP

מריצים את הפקודה הבאה מהספרייה שבה נמצא הקובץ app.yaml:

gcloud app deploy

Python

מריצים את הפקודה הבאה מהספרייה שבה נמצא הקובץ app.yaml:

gcloud app deploy

Ruby

מריצים את הפקודה הבאה מהספרייה שבה נמצא הקובץ app.yaml:

gcloud app deploy app.yaml

‎.NET

מריצים את הפקודה הבאה מהספרייה שבה נמצא הקובץ app.yaml:

gcloud app deploy

עכשיו יש לך גישה לאפליקציה בכתובת https://PROJECT_ID.REGION_ID.r.appspot.com. אפשר להשתמש בטופס כדי לשלוח הודעות, אבל אין ערובה לכך שמופע מסוים של האפליקציה יקבל את ההתראה. אפשר לשלוח כמה הודעות ולרענן את הדף כדי לראות את ההודעה שהתקבלה.