Como gravar e responder mensagens do Pub/Sub

ID da região

O REGION_ID é um código que o Google atribui com base na região selecionada ao criar o aplicativo. A inclusão de REGION_ID.r nos URLs do App Engine é opcional para aplicativos atuais e em breve será obrigatória para todos os aplicativos novos.

Para garantir uma transição tranquila, estamos atualizando lentamente o App Engine para usar IDs da região. Se ainda não tivermos atualizado seu projeto do Google Cloud, você não verá um ID da região para o aplicativo. Como o ID é opcional para os aplicativos atuais, não é necessário atualizar os URLs ou fazer outras alterações quando o ID da região está disponível para os aplicativos já existentes.

Saiba mais sobre IDs da região.

O Pub/Sub fornece mensagens assíncronas confiáveis de muitos para muitos entre aplicativos. Os aplicativos do editor podem enviar mensagens para um tópico e outros aplicativos podem se inscrever nesse tópico para receber as mensagens.

Neste documento, descrevemos como usar a biblioteca de cliente do Cloud para enviar e receber mensagens do Pub/Sub em um aplicativo Go.

Pré-requisitos

  • Siga as instruções em "Hello, World!" para Go no Google App Engine para configurar seu ambiente e projeto, e entender como os aplicativos Go do Google App Engine são estruturados.
  • Anote e guarde o ID do projeto. Você precisará dele para executar o aplicativo de amostra descrito neste documento.

Como clonar o app de amostra

Copie os aplicativos de amostra para sua máquina local e navegue até o diretório pubsub:

go get -u -d -v github.com/GoogleCloudPlatform/golang-samples/pubsub
cd $GOPATH/src/github.com/GoogleCloudPlatform/golang-samples/appengine_flexible/pubsub

Como criar um tópico e uma assinatura

Crie um tópico e uma assinatura. Isso inclui especificar o endpoint que receberá as solicitações do 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

Substitua YOUR_TOKEN por um token aleatório secreto. Ele é usado pelo endpoint do push para verificar as solicitações.

Definir variáveis de ambiente

Edite o arquivo app.yaml para definir as variáveis de ambiente do tópico e do token de verificação:

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

Revisão de código

No aplicativo de amostra, é usada a Biblioteca de cliente do Google Cloud Pub/Sub.

O aplicativo de amostra usa as variáveis de ambiente definidas no arquivo app.yaml (PUBSUB_TOPIC e PUBSUB_VERIFICATION_TOKEN) para a configuração.

As mensagens recebidas por essa instância são armazenadas em uma fatia:

messages   []string

A função pushHandler recebe mensagens enviadas, verifica o token e adiciona a mensagem à fração 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)
	}
	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:]
	}
}

A função publishHandler publica novas mensagens no tópico.


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

Como executar a amostra no local

Ao executar localmente, use o SDK do Cloud para fornecer autenticação de uso das APIs do Google Cloud. Se o ambiente tiver sido configurado conforme descrito emPré-requisitos, o comando gcloud init que fornece essa autenticação já terá sido executado.

Defina as variáveis de ambiente antes de iniciar o aplicativo:

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

Como simular notificações push

Pelo aplicativo, é possível enviar mensagens localmente, mas não é possível receber mensagens push localmente. É possível simular uma mensagem de push com uma solicitação HTTP para o notification endpoint de push local. A amostra inclui o sample_message.json do arquivo.

É possível usar curl ou um cliente httpie para enviar uma solicitação POST HTTP:

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

Ou

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

Resposta:

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

Após a conclusão da solicitação, é possível atualizar localhost:8080 e ver a mensagem na lista de mensagens recebidas.

Como executar no App Engine

Para implantar o aplicativo de demonstração no App Engine usando a ferramenta de linha de comando gcloud, execute o comando a seguir no diretório em que seu arquivo app.yaml está localizado:

gcloud app deploy

Agora é possível acessar o aplicativo em https://PROJECT_ID.REGION_ID.r.appspot.com. Use o formulário para enviar mensagens, mas não há garantias de qual instância do seu aplicativo receberá a notificação. É possível enviar várias mensagens e atualizar a página para ver a mensagem recebida.