Receive messages from a pull subscription
Stay organized with collections
Save and categorize content based on your preferences.
This document describes how to receive messages from a pull subscription. You can use the Google Cloud console, the Google Cloud CLI, the client library, or the Pub/Sub API to create a pull subscription.
Before you begin
- Create a pull subscription.
Required roles and permissions
To get the permission that
you need to receive messages from a pull subscription,
ask your administrator to grant you the
Pub/Sub Subscriber (roles/pubsub.subscriber) IAM role on the subscription.
For more information about granting roles, see Manage access to projects, folders, and organizations.
This predefined role contains the
pubsub.subscriptions.consume
permission,
which is required to
receive messages from a pull subscription.
You might also be able to get this permission with custom roles or other predefined roles.
Pull a message from a subscription
The following samples demonstrate how to pull a message from a subscription using either the StreamingPull API or the Pull API.
StreamingPull API
To use the StreamingPull API, you must use a client library.
The Google Cloud console and Google Cloud CLI don't support the StreamingPull API.
StreamingPull and high-level client library code samples
C++
Before trying this sample, follow the C++ setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C++ API reference documentation.
namespacepubsub=::google::cloud::pubsub;
autosample=[](pubsub::Subscribersubscriber){
returnsubscriber.Subscribe(
[&](pubsub::Messageconst&m,pubsub::AckHandlerh){
std::cout << "Received message " << m << "\n";
std::move(h).ack();
PleaseIgnoreThisSimplifiesTestingTheSamples();
});
};C#
Before trying this sample, follow the C# setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C# API reference documentation.
usingGoogle.Cloud.PubSub.V1 ;
usingSystem;
usingSystem.Threading;
usingSystem.Threading.Tasks;
publicclassPullMessagesAsyncSample
{
publicasyncTask<int>PullMessagesAsync(stringprojectId,stringsubscriptionId,boolacknowledge)
{
SubscriptionName subscriptionName=SubscriptionName .FromProjectSubscription (projectId,subscriptionId);
SubscriberClient subscriber=awaitSubscriberClient .CreateAsync (subscriptionName);
// SubscriberClient runs your message handle function on multiple
// threads to maximize throughput.
intmessageCount=0;
TaskstartTask=subscriber.StartAsync ((PubsubMessage message,CancellationTokencancel)=>
{
stringtext=message.Data.ToStringUtf8();
Console.WriteLine($"Message {message.MessageId}: {text}");
Interlocked.Increment(refmessageCount);
returnTask.FromResult(acknowledge?SubscriberClient .Reply .Ack :SubscriberClient .Reply .Nack );
});
// Run for 5 seconds.
awaitTask.Delay(5000);
awaitsubscriber.StopAsync (CancellationToken.None);
// Lets make sure that the start task finished successfully after the call to stop.
awaitstartTask;
returnmessageCount;
}
}Go
The following sample uses the major version of the Go Pub/Sub client library (v2). If you are still using the v1 library, see the migration guide to v2. To see a list of v1 code samples, see the deprecated code samples.
Before trying this sample, follow the Go setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Go API reference documentation.
import(
"context"
"fmt"
"io"
"sync/atomic"
"time"
"cloud.google.com/go/pubsub/v2"
)
funcpullMsgs(wio.Writer,projectID,subIDstring)error{
// projectID := "my-project-id"
// subID := "my-sub"
ctx:=context.Background()
client,err:=pubsub.NewClient(ctx,projectID)
iferr!=nil{
returnfmt.Errorf("pubsub.NewClient: %w",err)
}
deferclient.Close()
// client.Subscriber can be passed a subscription ID (e.g. "my-sub") or
// a fully qualified name (e.g. "projects/my-project/subscriptions/my-sub").
// If a subscription ID is provided, the project ID from the client is used.
sub:=client.Subscriber(subID)
// Receive messages for 10 seconds, which simplifies testing.
// Comment this out in production, since `Receive` should
// be used as a long running operation.
ctx,cancel:=context.WithTimeout(ctx,10*time.Second)
defercancel()
varreceivedint32
err=sub.Receive(ctx,func(_context.Context,msg*pubsub.Message){
fmt.Fprintf(w,"Got message: %q\n",string(msg.Data))
atomic.AddInt32(&received,1)
msg.Ack()
})
iferr!=nil{
returnfmt.Errorf("sub.Receive: %w",err)
}
fmt.Fprintf(w,"Received %d messages\n",received)
returnnil
}
Java
Before trying this sample, follow the Java setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Java API reference documentation.
importcom.google.cloud.pubsub.v1.AckReplyConsumer ;
importcom.google.cloud.pubsub.v1.MessageReceiver ;
importcom.google.cloud.pubsub.v1.Subscriber ;
importcom.google.pubsub.v1.ProjectSubscriptionName ;
importcom.google.pubsub.v1.PubsubMessage ;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.TimeoutException;
publicclass SubscribeAsyncExample{
publicstaticvoidmain(String...args)throwsException{
// TODO(developer): Replace these variables before running the sample.
StringprojectId="your-project-id";
StringsubscriptionId="your-subscription-id";
subscribeAsyncExample(projectId,subscriptionId);
}
publicstaticvoidsubscribeAsyncExample(StringprojectId,StringsubscriptionId){
ProjectSubscriptionName subscriptionName=
ProjectSubscriptionName .of(projectId,subscriptionId);
// Instantiate an asynchronous message receiver.
MessageReceiver receiver=
(PubsubMessagemessage,AckReplyConsumerconsumer)->{
// Handle incoming message, then ack the received message.
System.out.println("Id: "+message.getMessageId());
System.out.println("Data: "+message.getData().toStringUtf8());
consumer.ack();
};
Subscriber subscriber=null;
try{
subscriber=Subscriber .newBuilder(subscriptionName,receiver).build();
// Start the subscriber.
subscriber.startAsync ().awaitRunning();
System.out.printf("Listening for messages on %s:\n",subscriptionName.toString ());
// Allow the subscriber to run for 30s unless an unrecoverable error occurs.
subscriber.awaitTerminated(30,TimeUnit.SECONDS);
}catch(TimeoutExceptiontimeoutException){
// Shut down the subscriber after 30s. Stop receiving messages.
subscriber.stopAsync();
}
}
}Node.js
Before trying this sample, follow the Node.js setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Node.js API reference documentation.
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
// const timeout = 60;
// Imports the Google Cloud client library
const{PubSub}=require('@google-cloud/pubsub');
// Creates a client; cache this for further use
constpubSubClient=newPubSub ();
functionlistenForMessages(subscriptionNameOrId,timeout){
// References an existing subscription; if you are unsure if the
// subscription will exist, try the optimisticSubscribe sample.
constsubscription=pubSubClient.subscription(subscriptionNameOrId);
// Create an event handler to handle messages
letmessageCount=0;
constmessageHandler=message=>{
console.log(`Received message ${message.id}:`);
console.log(`\tData: ${message.data}`);
console.log(`\tAttributes: ${message.attributes}`);
messageCount+=1;
// "Ack" (acknowledge receipt of) the message
message.ack ();
};
// Listen for new messages until timeout is hit
subscription .on ('message',messageHandler);
// Wait a while for the subscription to run. (Part of the sample only.)
setTimeout(()=>{
subscription.removeListener('message',messageHandler);
console.log(`${messageCount} message(s) received.`);
},timeout*1000);
}Node.js
Before trying this sample, follow the Node.js setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Node.js API reference documentation.
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
// const timeout = 60;
// Imports the Google Cloud client library
import{PubSub,Message}from'@google-cloud/pubsub';
// Creates a client; cache this for further use
constpubSubClient=newPubSub();
functionlistenForMessages(subscriptionNameOrId:string,timeout:number){
// References an existing subscription; if you are unsure if the
// subscription will exist, try the optimisticSubscribe sample.
constsubscription=pubSubClient.subscription(subscriptionNameOrId);
// Create an event handler to handle messages
letmessageCount=0;
constmessageHandler=(message:Message)=>{
console.log(`Received message ${message.id}:`);
console.log(`\tData: ${message.data}`);
console.log(`\tAttributes: ${message.attributes}`);
messageCount+=1;
// "Ack" (acknowledge receipt of) the message
message.ack();
};
// Listen for new messages until timeout is hit
subscription.on('message',messageHandler);
// Wait a while for the subscription to run. (Part of the sample only.)
setTimeout(()=>{
subscription.removeListener('message',messageHandler);
console.log(`${messageCount} message(s) received.`);
},timeout*1000);
}Python
Before trying this sample, follow the Python setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Python API reference documentation.
fromconcurrent.futuresimport TimeoutError
fromgoogle.cloudimport pubsub_v1
# TODO(developer)
# project_id = "your-project-id"
# subscription_id = "your-subscription-id"
# Number of seconds the subscriber should listen for messages
# timeout = 5.0
subscriber = pubsub_v1.SubscriberClient ()
# The `subscription_path` method creates a fully qualified identifier
# in the form `projects/{project_id}/subscriptions/{subscription_id}`
subscription_path = subscriber.subscription_path(project_id, subscription_id)
defcallback(message: pubsub_v1.subscriber.message.Message ) -> None:
print(f"Received {message}.")
message.ack ()
streaming_pull_future = subscriber.subscribe (subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}..\n")
# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
try:
# When `timeout` is not set, result() will block indefinitely,
# unless an exception is encountered first.
streaming_pull_future.result(timeout=timeout)
except TimeoutError:
streaming_pull_future.cancel() # Trigger the shutdown.
streaming_pull_future.result() # Block until the shutdown is complete.Ruby
The following sample uses Ruby Pub/Sub client library v3. If you are still using the v2 library, see the migration guide to v3. To see a list of Ruby v2 code samples, see the deprecated code samples.
Before trying this sample, follow the Ruby setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Ruby API reference documentation.
# subscription_id = "your-subscription-id"
pubsub=Google::Cloud::PubSub .new
subscriber=pubsub.subscriber subscription_id
listener=subscriber.listen do|received_message|
puts"Received message: #{received_message.data}"
received_message.acknowledge!
end
listener.start
# Let the main thread sleep for 60 seconds so the thread for listening
# messages does not quit
sleep60
listener.stop.wait!Retrieve custom attributes using the high-level client library
The following samples show how to pull messages asynchronously and retrieve the custom attributes from the metadata.
C++
Before trying this sample, follow the C++ setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C++ API reference documentation.
namespacepubsub=::google::cloud::pubsub;
autosample=[](pubsub::Subscribersubscriber){
returnsubscriber.Subscribe(
[&](pubsub::Messageconst&m,pubsub::AckHandlerh){
std::cout << "Received message with attributes:\n";
for(auto&kv:m.attributes()){
std::cout << " " << kv.first << ": " << kv.second << "\n";
}
std::move(h).ack();
PleaseIgnoreThisSimplifiesTestingTheSamples();
});
};C#
Before trying this sample, follow the C# setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C# API reference documentation.
usingGoogle.Cloud.PubSub.V1 ;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Threading;
usingSystem.Threading.Tasks;
publicclassPullMessagesWithCustomAttributesAsyncSample
{
publicasyncTask<List<PubsubMessage>>PullMessagesWithCustomAttributesAsync(stringprojectId,stringsubscriptionId,boolacknowledge)
{
SubscriptionName subscriptionName=SubscriptionName .FromProjectSubscription (projectId,subscriptionId);
SubscriberClient subscriber=awaitSubscriberClient .CreateAsync (subscriptionName);
varmessages=newList<PubsubMessage>();
TaskstartTask=subscriber.StartAsync ((PubsubMessagemessage,CancellationTokencancel)=>
{
messages.Add(message);
stringtext=message.Data .ToStringUtf8();
Console.WriteLine($"Message {message.MessageId}: {text}");
if(message.Attributes!=null)
{
foreach(varattributeinmessage.Attributes)
{
Console.WriteLine($"{attribute.Key} = {attribute.Value}");
}
}
returnTask.FromResult(acknowledge?SubscriberClient .Reply .Ack :SubscriberClient .Reply .Nack );
});
// Run for 7 seconds.
awaitTask.Delay(7000);
awaitsubscriber.StopAsync (CancellationToken.None);
// Lets make sure that the start task finished successfully after the call to stop.
awaitstartTask;
returnmessages;
}
}Go
The following sample uses the major version of the Go Pub/Sub client library (v2). If you are still using the v1 library, see the migration guide to v2. To see a list of v1 code samples, see the deprecated code samples.
Before trying this sample, follow the Go setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Go API reference documentation.
import(
"context"
"fmt"
"io"
"time"
"cloud.google.com/go/pubsub/v2"
)
funcpullMsgsCustomAttributes(wio.Writer,projectID,subIDstring)error{
// projectID := "my-project-id"
// subID := "my-sub"
ctx:=context.Background()
client,err:=pubsub.NewClient(ctx,projectID)
iferr!=nil{
returnfmt.Errorf("pubsub.NewClient: %w",err)
}
deferclient.Close()
// client.Subscriber can be passed a subscription ID (e.g. "my-sub") or
// a fully qualified name (e.g. "projects/my-project/subscriptions/my-sub").
// If a subscription ID is provided, the project ID from the client is used.
sub:=client.Subscriber(subID)
// Receive messages for 10 seconds, which simplifies testing.
// Comment this out in production, since `Receive` should
// be used as a long running operation.
ctx,cancel:=context.WithTimeout(ctx,10*time.Second)
defercancel()
// Receive blocks until the context is cancelled or an error occurs.
err=sub.Receive(ctx,func(_context.Context,msg*pubsub.Message){
fmt.Fprintf(w,"Got message :%q\n",string(msg.Data))
fmt.Fprintln(w,"Attributes:")
forkey,value:=rangemsg.Attributes{
fmt.Fprintf(w,"%s = %s\n",key,value)
}
msg.Ack()
})
iferr!=nil{
returnfmt.Errorf("sub.Receive: %w",err)
}
returnnil
}
Java
Before trying this sample, follow the Java setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Java API reference documentation.
importcom.google.cloud.pubsub.v1.AckReplyConsumer ;
importcom.google.cloud.pubsub.v1.MessageReceiver ;
importcom.google.cloud.pubsub.v1.Subscriber ;
importcom.google.pubsub.v1.ProjectSubscriptionName ;
importcom.google.pubsub.v1.PubsubMessage ;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.TimeoutException;
publicclass SubscribeWithCustomAttributesExample{
publicstaticvoidmain(String...args)throwsException{
// TODO(developer): Replace these variables before running the sample.
StringprojectId="your-project-id";
StringsubscriptionId="your-subscription-id";
subscribeWithCustomAttributesExample(projectId,subscriptionId);
}
publicstaticvoidsubscribeWithCustomAttributesExample(StringprojectId,StringsubscriptionId){
ProjectSubscriptionName subscriptionName=
ProjectSubscriptionName .of(projectId,subscriptionId);
// Instantiate an asynchronous message receiver.
MessageReceiver receiver=
(PubsubMessagemessage,AckReplyConsumerconsumer)->{
// Handle incoming message, then ack the received message.
System.out.println("Id: "+message.getMessageId());
System.out.println("Data: "+message.getData().toStringUtf8());
// Print message attributes.
message
.getAttributesMap()
.forEach((key,value)->System.out.println(key+" = "+value));
consumer.ack();
};
Subscriber subscriber=null;
try{
subscriber=Subscriber .newBuilder(subscriptionName,receiver).build();
// Start the subscriber.
subscriber.startAsync ().awaitRunning();
System.out.printf("Listening for messages on %s:\n",subscriptionName.toString ());
// Allow the subscriber to run for 30s unless an unrecoverable error occurs.
subscriber.awaitTerminated(30,TimeUnit.SECONDS);
}catch(TimeoutExceptiontimeoutException){
// Shut down the subscriber after 30s. Stop receiving messages.
subscriber.stopAsync();
}
}
}Node.js
Before trying this sample, follow the Node.js setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Node.js API reference documentation.
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
// const timeout = 60;
// Imports the Google Cloud client library
const{PubSub}=require('@google-cloud/pubsub');
// Creates a client; cache this for further use
constpubSubClient=newPubSub ();
asyncfunctionlistenWithCustomAttributes(subscriptionNameOrId,timeout){
// References an existing subscription, e.g. "my-subscription"
constsubscription=pubSubClient.subscription(subscriptionNameOrId);
// Create an event handler to handle messages
constmessageHandler=message=>{
console.log(
`Received message: id ${message.id}, data ${
message.data
}, attributes: ${JSON.stringify(message.attributes)}`,
);
// "Ack" (acknowledge receipt of) the message
message.ack ();
};
// Wait a while for the subscription to run. (Part of the sample only.)
subscription .on ('message',messageHandler);
setTimeout(()=>{
subscription.removeListener('message',messageHandler);
},timeout*1000);
}Python
Before trying this sample, follow the Python setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Python API reference documentation.
fromconcurrent.futuresimport TimeoutError
fromgoogle.cloudimport pubsub_v1
# TODO(developer)
# project_id = "your-project-id"
# subscription_id = "your-subscription-id"
# Number of seconds the subscriber should listen for messages
# timeout = 5.0
subscriber = pubsub_v1.SubscriberClient ()
subscription_path = subscriber.subscription_path(project_id, subscription_id)
defcallback(message: pubsub_v1.subscriber.message.Message ) -> None:
print(f"Received {message.data !r}.")
if message.attributes :
print("Attributes:")
for key in message.attributes :
value = message.attributes .get(key)
print(f"{key}: {value}")
message.ack ()
streaming_pull_future = subscriber.subscribe (subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}..\n")
# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
try:
# When `timeout` is not set, result() will block indefinitely,
# unless an exception is encountered first.
streaming_pull_future.result(timeout=timeout)
except TimeoutError:
streaming_pull_future.cancel() # Trigger the shutdown.
streaming_pull_future.result() # Block until the shutdown is complete.Ruby
The following sample uses Ruby Pub/Sub client library v3. If you are still using the v2 library, see the migration guide to v3. To see a list of Ruby v2 code samples, see the deprecated code samples.
Before trying this sample, follow the Ruby setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Ruby API reference documentation.
# subscription_id = "your-subscription-id"
pubsub=Google::Cloud::PubSub .new
subscriber=pubsub.subscriber subscription_id
listener=subscriber.listen do|received_message|
puts"Received message: #{received_message.data}"
unlessreceived_message.attributes.empty?
puts"Attributes:"
received_message.attributes.eachdo|key,value|
puts"#{key}: #{value}"
end
end
received_message.acknowledge!
end
listener.start
# Let the main thread sleep for 60 seconds so the thread for listening
# messages does not quit
sleep60
listener.stop.wait!Handle errors using the high-level client library
The following samples show how to handle errors that arise when subscribing to messages.
C++
Before trying this sample, follow the C++ setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C++ API reference documentation.
namespacepubsub=::google::cloud::pubsub;
using::google::cloud::future;
autosample=[](pubsub::Subscribersubscriber){
returnsubscriber
.Subscribe([&](pubsub::Messageconst&m,pubsub::AckHandlerh){
std::cout << "Received message " << m << "\n";
std::move(h).ack();
PleaseIgnoreThisSimplifiesTestingTheSamples();
})
// Setup an error handler for the subscription session
.then([](future<google::cloud::Status>f){
std::cout << "Subscription session result: " << f.get() << "\n";
});
};Go
The following sample uses the major version of the Go Pub/Sub client library (v2). If you are still using the v1 library, see the migration guide to v2. To see a list of v1 code samples, see the deprecated code samples.
Before trying this sample, follow the Go setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Go API reference documentation.
import(
"context"
"fmt"
"io"
"cloud.google.com/go/pubsub/v2"
)
funcpullMsgsError(wio.Writer,projectID,subIDstring)error{
// projectID := "my-project-id"
// subID := "my-sub"
ctx:=context.Background()
client,err:=pubsub.NewClient(ctx,projectID)
iferr!=nil{
returnfmt.Errorf("pubsub.NewClient: %w",err)
}
deferclient.Close()
// If the service returns a non-retryable error, Receive returns that error after
// all of the outstanding calls to the handler have returned.
// client.Subscriber can be passed a subscription ID (e.g. "my-sub") or
// a fully qualified name (e.g. "projects/my-project/subscriptions/my-sub").
// If a subscription ID is provided, the project ID from the client is used.
sub:=client.Subscriber(subID)
err=sub.Receive(ctx,func(ctxcontext.Context,msg*pubsub.Message){
fmt.Fprintf(w,"Got message: %q\n",string(msg.Data))
msg.Ack()
})
iferr!=nil{
returnfmt.Errorf("Receive: %w",err)
}
returnnil
}
Java
Before trying this sample, follow the Java setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Java API reference documentation.
importcom.google.api.gax.core.ExecutorProvider ;
importcom.google.api.gax.core.InstantiatingExecutorProvider ;
importcom.google.cloud.pubsub.v1.AckReplyConsumer ;
importcom.google.cloud.pubsub.v1.MessageReceiver ;
importcom.google.cloud.pubsub.v1.Subscriber ;
importcom.google.common.util.concurrent.MoreExecutors;
importcom.google.pubsub.v1.ProjectSubscriptionName ;
importcom.google.pubsub.v1.PubsubMessage ;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.TimeoutException;
publicclass SubscribeWithErrorListenerExample{
publicstaticvoidmain(String...args)throwsException{
// TODO(developer): Replace these variables before running the sample.
StringprojectId="your-project-id";
StringsubscriptionId="your-subscription-id";
subscribeWithErrorListenerExample(projectId,subscriptionId);
}
publicstaticvoidsubscribeWithErrorListenerExample(StringprojectId,StringsubscriptionId){
ProjectSubscriptionName subscriptionName=
ProjectSubscriptionName .of(projectId,subscriptionId);
// Instantiate an asynchronous message receiver.
MessageReceiver receiver=
(PubsubMessagemessage,AckReplyConsumerconsumer)->{
// Handle incoming message, then ack the received message.
System.out.println("Id: "+message.getMessageId());
System.out.println("Data: "+message.getData().toStringUtf8());
consumer.ack();
};
Subscriber subscriber=null;
try{
// Provides an executor service for processing messages.
ExecutorProvider executorProvider=
InstantiatingExecutorProvider .newBuilder().setExecutorThreadCount (4).build();
subscriber=
Subscriber .newBuilder(subscriptionName,receiver)
.setExecutorProvider(executorProvider)
.build();
// Listen for unrecoverable failures.
subscriber.addListener(
newSubscriber .Listener(){
publicvoidfailed(Subscriber .Statefrom,Throwablefailure){
System.out.println("Unrecoverable subscriber failure:"+failure.getStackTrace());
}
},
MoreExecutors.directExecutor());
// Start the subscriber.
subscriber.startAsync ().awaitRunning();
System.out.printf("Listening for messages on %s:\n",subscriptionName.toString ());
// Allow the subscriber to run for 30s unless an unrecoverable error occurs.
subscriber.awaitTerminated(30,TimeUnit.SECONDS);
}catch(TimeoutExceptiontimeoutException){
// Shut down the subscriber after 30s. Stop receiving messages.
subscriber.stopAsync();
}
}
}Node.js
Before trying this sample, follow the Node.js setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Node.js API reference documentation.
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
// const timeout = 10;
// Imports the Google Cloud client library
const{PubSub}=require('@google-cloud/pubsub');
// Creates a client; cache this for further use
constpubSubClient=newPubSub ();
functionlistenForErrors(subscriptionNameOrId,timeout){
// References an existing subscription
constsubscription=pubSubClient.subscription(subscriptionNameOrId);
// Create an event handler to handle messages
constmessageHandler=message=>{
// Do something with the message
console.log(`Message: ${message}`);
// "Ack" (acknowledge receipt of) the message
message.ack ();
};
// Create an event handler to handle errors
consterrorHandler=error=>{
// Do something with the error
console.error(`ERROR: ${error}`);
throwerror;
};
// Listen for new messages/errors until timeout is hit
subscription .on ('message',messageHandler);
subscription .on ('error',errorHandler);
// Wait a while for the subscription to run. (Part of the sample only.)
setTimeout(()=>{
subscription.removeListener('message',messageHandler);
subscription.removeListener('error',errorHandler);
},timeout*1000);
}Python
Before trying this sample, follow the Python setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Python API reference documentation.
fromgoogle.cloudimport pubsub_v1
# TODO(developer)
# project_id = "your-project-id"
# subscription_id = "your-subscription-id"
# Number of seconds the subscriber should listen for messages
# timeout = 5.0
subscriber = pubsub_v1.SubscriberClient ()
subscription_path = subscriber.subscription_path(project_id, subscription_id)
defcallback(message: pubsub_v1.subscriber.message.Message ) -> None:
print(f"Received {message}.")
message.ack ()
streaming_pull_future = subscriber.subscribe (subscription_path, callback=callback)
print(f"Listening for messages on {subscription_path}..\n")
# Wrap subscriber in a 'with' block to automatically call close() when done.
with subscriber:
# When `timeout` is not set, result() will block indefinitely,
# unless an exception is encountered first.
try:
streaming_pull_future.result(timeout=timeout)
except Exception as e:
print(
f"Listening for messages on {subscription_path} threw an exception: {e}."
)
streaming_pull_future.cancel() # Trigger the shutdown.
streaming_pull_future.result() # Block until the shutdown is complete.Ruby
The following sample uses Ruby Pub/Sub client library v3. If you are still using the v2 library, see the migration guide to v3. To see a list of Ruby v2 code samples, see the deprecated code samples.
Before trying this sample, follow the Ruby setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Ruby API reference documentation.
# subscription_id = "your-subscription-id"
pubsub=Google::Cloud::PubSub .new
subscriber=pubsub.subscriber subscription_id
listener=subscriber.listen do|received_message|
puts"Received message: #{received_message.data}"
received_message.acknowledge!
end
# Propagate exception from child threads to the main thread as soon as it is
# raised. Exceptions happened in the callback thread are collected in the
# callback thread pool and do not propagate to the main thread
Thread.abort_on_exception=true
begin
listener.start
# Let the main thread sleep for 60 seconds so the thread for listening
# messages does not quit
sleep60
listener.stop.wait!
rescueStandardError=>e
puts"Exception #{e.inspect}: #{e.message}"
raise"Stopped listening for messages."
endUnary pull
To use the Unary API, you can use the Google Cloud console, Google Cloud CLI, or a client library.
Considerations
Pub/Sub delivers a list of messages. If the list has multiple messages, Pub/Sub orders the messages with the same ordering key. The following are some important caveats:
Setting a value for
max_messagesin the request does not guarantee thatmax_messagesare returned, even if there are that many messages in the backlog. The Pub/Sub Pull API might return fewer thanmax_messagesin order to reduce the delivery latency for messages that are readily available to be delivered.A pull response that comes with 0 messages must not be used as an indicator that there are no messages in the backlog. It's possible to get a response with 0 messages and have a subsequent request that returns messages.
Console
In the Google Cloud console, go to the Pub/Sub subscriptions page.
Click the name of the subscription that you want to pull from.
In the Messages tab, click Pull.
You should see the messages that you published to this subscription and the time they were published.
When using the Google Cloud console with a low-volume subscription, it's possible that a Pull request returns zero messages. This is because the console uses Unary pull which does not guarantee low latency and a high throughput of messages. If no messages appear, initiate a new pull request when messages are available.
gcloud
To pull a message from a subscription, run the gcloud pubsub subscriptions pull
command. The gcloud CLI prints the message to the command line.
gcloudpubsubsubscriptionspullSUBSCRIPTION_NAME--auto-ack
Replace:
SUBSCRIPTION_NAME: The name of the subscription from which you want to pull messages.
Client Libraries
Here's some sample code to pull and acknowledge a fixed number of messages.
C++
Before trying this sample, follow the C++ setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C++ API reference documentation.
[](google::cloud::pubsub::Subscribersubscriber){
autoresponse=subscriber.Pull();
if(!response)throwstd::move(response).status();
std::cout << "Received message " << response->message << "\n";
std::move(response->handler).ack();
}C#
Before trying this sample, follow the C# setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub C# API reference documentation.
usingGoogle.Cloud.PubSub.V1 ;
usingGrpc.Core ;
usingSystem;
usingSystem.Linq;
usingSystem.Threading;
publicclassPullMessagesSyncSample
{
publicintPullMessagesSync(stringprojectId,stringsubscriptionId,boolacknowledge)
{
SubscriptionName subscriptionName=SubscriptionName .FromProjectSubscription (projectId,subscriptionId);
SubscriberServiceApiClient subscriberClient=SubscriberServiceApiClient .Create ();
intmessageCount=0;
try
{
// Pull messages from server,
// allowing an immediate response if there are no messages.
PullResponse response=subscriberClient.Pull (subscriptionName,maxMessages:20);
// Print out each received message.
foreach(ReceivedMessage msginresponse.ReceivedMessages )
{
stringtext=msg.Message.Data .ToStringUtf8();
Console.WriteLine($"Message {msg.Message.MessageId}: {text}");
Interlocked.Increment(refmessageCount);
}
// If acknowledgement required, send to server.
if(acknowledge && messageCount > 0)
{
subscriberClient.Acknowledge (subscriptionName,response.ReceivedMessages .Select(msg=>msg.AckId ));
}
}
catch(RpcException ex)when(ex.Status .StatusCode ==StatusCode .Unavailable )
{
// UNAVAILABLE due to too many concurrent pull requests pending for the given subscription.
}
returnmessageCount;
}
}Java
Before trying this sample, follow the Java setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Java API reference documentation.
importcom.google.cloud.pubsub.v1.stub.GrpcSubscriberStub;
importcom.google.cloud.pubsub.v1.stub.SubscriberStub ;
importcom.google.cloud.pubsub.v1.stub.SubscriberStubSettings;
importcom.google.pubsub.v1.AcknowledgeRequest ;
importcom.google.pubsub.v1.ProjectSubscriptionName ;
importcom.google.pubsub.v1.PullRequest ;
importcom.google.pubsub.v1.PullResponse ;
importcom.google.pubsub.v1.ReceivedMessage ;
importjava.io.IOException;
importjava.util.ArrayList;
importjava.util.List;
publicclass SubscribeSyncExample{
publicstaticvoidmain(String...args)throwsException{
// TODO(developer): Replace these variables before running the sample.
StringprojectId="your-project-id";
StringsubscriptionId="your-subscription-id";
IntegernumOfMessages=10;
subscribeSyncExample(projectId,subscriptionId,numOfMessages);
}
publicstaticvoidsubscribeSyncExample(
StringprojectId,StringsubscriptionId,IntegernumOfMessages)throwsIOException{
SubscriberStubSettingssubscriberStubSettings=
SubscriberStubSettings.newBuilder()
.setTransportChannelProvider(
SubscriberStubSettings.defaultGrpcTransportProviderBuilder()
.setMaxInboundMessageSize(20*1024*1024)// 20MB (maximum message size).
.build())
.build();
try(SubscriberStub subscriber=GrpcSubscriberStub.create(subscriberStubSettings)){
StringsubscriptionName=ProjectSubscriptionName .format(projectId,subscriptionId);
PullRequest pullRequest=
PullRequest .newBuilder()
.setMaxMessages(numOfMessages)
.setSubscription(subscriptionName)
.build();
// Use pullCallable().futureCall to asynchronously perform this operation.
PullResponse pullResponse=subscriber.pullCallable().call(pullRequest);
// Stop the program if the pull response is empty to avoid acknowledging
// an empty list of ack IDs.
if(pullResponse.getReceivedMessagesList ().isEmpty()){
System.out.println("No message was pulled. Exiting.");
return;
}
List<String>ackIds=newArrayList<>();
for(ReceivedMessage message:pullResponse.getReceivedMessagesList ()){
// Handle received message
// ...
ackIds.add(message.getAckId());
}
// Acknowledge received messages.
AcknowledgeRequest acknowledgeRequest=
AcknowledgeRequest .newBuilder()
.setSubscription(subscriptionName)
.addAllAckIds(ackIds)
.build();
// Use acknowledgeCallable().futureCall to asynchronously perform this operation.
subscriber.acknowledgeCallable().call(acknowledgeRequest);
System.out.println(pullResponse.getReceivedMessagesList ());
}
}
}Node.js
Before trying this sample, follow the Node.js setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Node.js API reference documentation.
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
// const projectId = 'YOUR_PROJECT_ID';
// const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
// Imports the Google Cloud client library. v1 is for the lower level
// proto access.
const{v1}=require('@google-cloud/pubsub');
// Creates a client; cache this for further use.
constsubClient=newv1.SubscriberClient ();
asyncfunctionsynchronousPull(projectId,subscriptionNameOrId){
// The low level API client requires a name only.
constformattedSubscription=
subscriptionNameOrId.indexOf('/')>=0
?subscriptionNameOrId
:subClient.subscriptionPath(projectId,subscriptionNameOrId);
// The maximum number of messages returned for this request.
// Pub/Sub may return fewer than the number specified.
constrequest={
subscription:formattedSubscription,
maxMessages:10,
};
// The subscriber pulls a specified number of messages.
const[response]=awaitsubClient.pull(request);
// Process the messages.
constackIds=[];
for(constmessageofresponse.receivedMessages||[]){
console.log(`Received message: ${message.message.data}`);
if(message.ackId){
ackIds.push(message.ackId);
}
}
if(ackIds.length !==0){
// Acknowledge all of the messages. You could also acknowledge
// these individually, but this is more efficient.
constackRequest={
subscription:formattedSubscription,
ackIds:ackIds,
};
awaitsubClient.acknowledge(ackRequest);
}
console.log('Done.');
}PHP
Before trying this sample, follow the PHP setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub PHP API reference documentation.
use Google\Cloud\PubSub\PubSubClient;
/**
* Pulls all Pub/Sub messages for a subscription.
*
* @param string $projectId The Google project ID.
* @param string $subscriptionName The Pub/Sub subscription name.
*/
function pull_messages($projectId, $subscriptionName)
{
$pubsub = new PubSubClient([
'projectId' => $projectId,
]);
$subscription = $pubsub->subscription($subscriptionName);
foreach ($subscription->pull() as $message) {
printf('Message: %s' . PHP_EOL, $message->data());
// Acknowledge the Pub/Sub message has been received, so it will not be pulled multiple times.
$subscription->acknowledge($message);
}
}Ruby
The following sample uses Ruby Pub/Sub client library v3. If you are still using the v2 library, see the migration guide to v3. To see a list of Ruby v2 code samples, see the deprecated code samples.
Before trying this sample, follow the Ruby setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Ruby API reference documentation.
# subscription_id = "your-subscription-id"
pubsub=Google::Cloud::PubSub .new
subscriber=pubsub.subscriber subscription_id
subscriber.pull(immediate:false).eachdo|message|
puts"Message pulled: #{message.data}"
message.acknowledge!
endProtocol
Request:
POST https://pubsub.googleapis.com/v1/projects/myproject/subscriptions/mysubscription:pull
{
"returnImmediately":"false",
"maxMessages":"1"
}
Response:
200 OK
{
"receivedMessages":[{
"ackId":"dQNNHlAbEGEIBERNK0EPKVgUWQYyODM2LwgRHFEZDDsLRk1SK...",
"message":{
"data":"SGVsbG8gQ2xvdWQgUHViL1N1YiEgSGVyZSBpcyBteSBtZXNzYWdlIQ==",
"messageId":"19917247034"
}
}]
}
Request:
POST https://pubsub.googleapis.com/v1/projects/myproject/subscriptions/mysubscription:acknowledge
{
"ackIds":[
"dQNNHlAbEGEIBERNK0EPKVgUWQYyODM2LwgRHFEZDDsLRk1SK..."
]
}
Python
Before trying this sample, follow the Python setup instructions in Quickstart: Using Client Libraries. For more information, see the Pub/Sub Python API reference documentation.
fromgoogle.api_coreimport retry
fromgoogle.cloudimport pubsub_v1
# TODO(developer)
# project_id = "your-project-id"
# subscription_id = "your-subscription-id"
subscriber = pubsub_v1.SubscriberClient ()
subscription_path = subscriber.subscription_path(project_id, subscription_id)
NUM_MESSAGES = 3
# Wrap the subscriber in a 'with' block to automatically call close() to
# close the underlying gRPC channel when done.
with subscriber:
# The subscriber pulls a specific number of messages. The actual
# number of messages pulled may be smaller than max_messages.
response = subscriber.pull (
request={"subscription": subscription_path, "max_messages": NUM_MESSAGES},
retry=retry .Retry(deadline=300),
)
if len(response.received_messages) == 0:
return
ack_ids = []
for received_message in response.received_messages:
print(f"Received: {received_message.message.data }.")
ack_ids.append(received_message.ack_id )
# Acknowledges the received messages so they will not be sent again.
subscriber.acknowledge (
request={"subscription": subscription_path, "ack_ids": ack_ids}
)
print(
f"Received and acknowledged {len(response.received_messages)} messages from {subscription_path}."
)What's next
- Create or modify a subscription with
gcloudcommands. - Create or modify a subscription with REST APIs.
- Create or modify a subscription with RPC APIs.