Client-side apps

A client-side push-enabled app runs on a device. It uses the Push Service to communicate with a server-side app, called a push initiator. Before you develop your own push-enabled app, you may find it helpful to try out the Simple Push Client and Simple Push Server sample apps available on GitHub.

You can use the following code samples to develop your own push-enabled app. The code samples show you how to connect to the server-side push initiator and receive push messages on a BlackBerry device. To learn how to create a server-side push initiator, see Server-side: consumer apps and Server-side: enterprise apps.

In your app, you can send up to 8 KB of any type of content (images, text, or audio). The code samples can be used to create an app that accepts push messages with the following types of content and content-type HTTP headers:

  • Text: text/plain
  • HTML: text/html
  • XML: application/xml
  • Image: image/jpeg, image/gif, image/png

If you're using the Push Service SDK to build your server-side push initiator, the SDK automatically specifies the type of content in the header of the push message.

You can develop a client-side push-enabled app by using the C++ Push APIs or the C Push Service APIs.

Prerequisites

To develop and test a client-side push-enabled app, you need the following:

  • A server-side push initiator to test your app
  • The provider application ID and the PPG URL for your server-side push app
  • The BlackBerry 10 Native SDK
  • A device running BlackBerry 10

If you are developing a consumer server-side push initiator, when you register to evaluate the Push Service, the provider application ID and the PPG URL are included in the confirmation email from BlackBerry. Enterprise push client apps don’t need to register for the Push Service with BlackBerry but they still need the application ID and invocation Target ID information.

Your app needs the Push permission (_sys_use_consumer_push) to receive push messages. If you are using BES10 or later, you don't need this permission.

Register to use the Push Service

You need to be registered to test your client-side push app. Fill out the BlackBerry Push Service Evaluation Form.

If you are creating an enterprise app that sends pushes only through BES10 or BES12, you don't need to register.

When your application is approved, you receive an email that confirms your registration details and provides the following information:

Account Administration Portal
  • Portal URL: https://cpadmin.pushapi.eval.blackberry.com/mss/CP_login
  • Portal Username: <your email address>
  • Portal Password
Server Configuration Details
  • Application ID
  • Push Password
  • Content Provider ID (CPID)
  • Account Expiration Date
  • Push URL: https://cp<your CPID>.pushapi.eval.blackberry.com
Client Configuration Details
  • Application ID
  • Push Registration URL: http://cp<your CPID>.pushapi.eval.blackberry.com
  • Push Port

The Application ID is the same for your server-side and client-side apps. You can ignore the Push Port because it is not required for BlackBerry 10 push apps.

Configure your bar-descriptor.xml file

If you are developing a consumer app, add an invoke target that receives the push message in your client-side push-enabled app. The invoke-target id must match the app name that you registered. For example:

<invoke-target id="com.example.pushCollector.invoke.push">
    <type>APPLICATION</type>
    <filter>
        <action>bb.action.PUSH</action>
        <mime-type>application/vnd.push</mime-type>
    </filter>
</invoke-target>

You must also add an entry for an open invoke event that the consumer app receives. For example:

<invoke-target id="com.example.pushCollector.invoke.open">
    <type>APPLICATION</type>
    <filter>
        <action>bb.action.OPEN</action>
        <mime-type>text/plain</mime-type>
    </filter>
</invoke-target>

If you are creating an enterprise app that sends pushes only through a BlackBerry Enterprise Server, you must add a slightly different invoke target that receives the push in your app. The target ID must be unique for your company and app. For example:

<invoke-target id="com.yourcompany.pushCollector">
      <type>APPLICATION</type>
      <filter>
         <action>bb.action.PUSH</action>
         <mime-type>application/vnd.push</mime-type>
      </filter>
    </invoke-target>

Create a Push Service instance

The following code samples demonstrate how to initialize a push session and perform push-related operations. You should create only one instance of the Push Service in your app. If you are using the C++ APIs, you create a PushService object. If you are using the C APIs, you create a push_service_t structure.

The Push Service performs the following actions:

  • Registers a user to receive push messages
  • Handles incoming push messages
  • Unregisters a user and stops the user from receiving pushes
  • Handles a SIM card change by creating one instance of the Push Service and associating it with one provider ApplicationID and one invokeTargetID

Not applicable

If you are developing a consumer app, create a PushService instance as follows:

const QString PushManager::BLACKBERRY_INVOKE_TARGET_ID = "com.samples.push.simple";
const QString PushManager::BLACKBERRY_PUSH_APPLICATION_ID = "Application ID";
const QString PushManager::BLACKBERRY_PUSH_URL = "http://pushapi.eval.blackberry.com";

// Create a PushService instance so that the device knows 
// how to invoke our app when a push arrives
m_pushService = new PushService(BLACKBERRY_PUSH_APPLICATION_ID, 
                                BLACKBERRY_INVOKE_TARGET_ID);

If you are creating an enterprise app that sends pushes only through a BlackBerry Enterprise Server, create a PushService instance as follows:

const  QString PushManager::BLACKBERRY_INVOKE_TARGET_ID  = "com.yourcompany.pushCollector";
const  QString PushManager::BLACKBERRY_PUSH_APPLICATION_ID  = "BBPushCollector";
const  QString PushManager::BLACKBERRY_PUSH_URL  ="";

// Create a push service so that the device knows 
// how to invoke our app when a push arrives
m_pushService = new PushService(BLACKBERRY_PUSH_APPLICATION_ID, 
                                BLACKBERRY_INVOKE_TARGET_ID);

Connect the slots for the createSessionCompleted() and createChannelCompleted() signals as follows:

connect(m_pushService,
    SIGNAL(createSessionCompleted (const bb::network::PushStatus &)),
    this,
    SLOT(createSessionCompleted(const bb::network::PushStatus&)));


// ...

connect(m_pushService,
    SIGNAL(createChannelCompleted (const bb::network::PushStatus&, const QString &)), 
    this,
    SLOT(createChannelCompleted(const bb::network::PushStatus&, const QString &)));

To use the C APIs from the Push Service library, create a push_service_t structure in your app.

push_service_t *ps = NULL;
int rc = push_service_initialize(&ps);
if ((rc == PUSH_FAILURE) || (ps == NULL)){
    printf("start_push_service: failed init push_service errno[%d] 
       error[%s]\n", errno, strerror(errno));

    return EXIT_FAILURE;
}

Create a Push Notification Service (PNS) session

Creating a session sets up interprocess communication between the app and the Push Service. You should create a PNS session when you initialize the app.

Not applicable

// Create a PNS session to start receiving push messages
m_pushService ->createSession();

To create a PNS session, you need to pass in the provider application ID and the invoke target key. You received the provider application ID when you registered with BlackBerry to use the Push Service. The invoke target key is a value that you generate. This value identifies your push-enabled app as the target of push content, and the app to invoke when the content arrives.

rc = push_service_set_provider_application_id(ps, provider_app_id);
if (rc == PUSH_FAILURE) {
	printf("push_service_set_provider_application_id: errno[%d] 
	error[%s]\n", errno, strerror(errno));
	return false;
}
rc = push_service_set_target_key(ps, target_key);
if (rc == PUSH_FAILURE) {
	printf("push_service_set_target_key: errno[%d] error[%s]\n", 
	errno, strerror(errno));
	return false;
}

rc = push_service_create_session(ps, on_create_session_complete);
if (rc == PUSH_FAILURE) {
	printf("push_service_create_session: errno[%d] error[%s]\n",
	errno, strerror(errno));
	return false;
}

// The status_code parameter of on_create_session_complete()
// contains the result of the create session call. If there 
// are no errors, the status code is 0. If there is an error,
// status_code contains the result code.

void on_create_session_complete(push_service_t* ps, int status_code)

Create a push channel

The following code sample creates a push channel to the PPG to receive push messages. Your app needs to create a channel only the first time it starts, or if the channel was destroyed and you want to start receiving push messages again. When the PNS session is created successfully, your app can create the push channel by registering with the Push Service.

Not applicable

/* 
* When the session is created successfully, create the 
* channel (register with the Push Service)
*/
void PushManager::createSessionCompleted(
		const bb::network::PushStatus& status) {
	if (!status.isError() && m_pushService) {
		log("Session creation completed successfully");
		// ...
		m_pushService->createChannel(QUrl(BLACKBERRY_PUSH_URL));

	} else {
		log("Session creation failed: " + status.errorDescription());
	}
} 

Pass an empty string as the URL for BlackBerry Enterprise Push.

// Create a channel to the PPG using push_service_create_channel()
// to receive content that is sent from the PPG

void on_create_channel_complete(push_service_t* ps, int status_code) {
    printf("on_create_channel_complete called statusCode[%d]", 
            status_code);
}

void create_channel_on_push_transport_ready(push_service_t* ps, 
int status_code) {
    push_service_create_channel(
        ps, 
        on_create_channel_complete, 
        create_channel_on_push_transport_ready);
}
// Send the request to create a channel through the PNS agent.
// You need the PPG URL to invoke the call to create a channel.
// You received the PPG URL when you registered with BlackBerry
// to use the Push Service.

rc = push_service_set_ppg_url(ps, ppg_url);
if (rc == PUSH_SUCCESS) {
    rc = push_service_create_channel(
        ps, 
        on_create_channel_complete,
        create_channel_on_push_transport_ready);
}
else{
    // Handle the situation where the push_service_create_channel()
    // request fails with a PUSH_ERR_TRANSPORT_FAILURE (10103)
    // or PUSH_ERR_PPG_SERVER_ERROR (10110) status code.

    printf("push_service_set_ppg_url: errno[%d] error[%s]", errno,
            strerror(errno));
}

Register to launch

You can configure the Push Service to start running your app in the background when it receives a push message. If the push channel was created successfully, call registerToLaunch() to register your app to be launched in the background when it receives a push message. If you want to see push messages only when your app is open, you don’t need to call registerToLaunch().

The following code sample registers the app to be launched in the background when it receives a push message.

Not applicable

/** 
* If the channel was created successfully, register to launch the app 
* so that the app opens when a push arrives.
*/
void PushManager::createChannelCompleted(const bb::network::PushStatus& status, const QString& token) {
	Q_UNUSED(token);
	if (!status.isError() && m_pushService) {
		log("Channel creation completed successfully");
		m_pushService->registerToLaunch();
	} else {
		log("Channel creation failed: " + status.errorDescription());
	}
}

Not applicable

The following code sample cancels a previous registerToLaunch() request.

Not applicable

m_pushService >unregisterFromLaunch();

Not applicable

You can close the app after it processes a push message by canceling the previous registerToLaunch() request.

Receive a push message

When a push message arrives on the device, the Push Service matches the application ID in the push header to a client-side push-enabled app that's registered with the Push Service. The Push Service then invokes the app that is associated with the ID.

Not applicable

In this code sample, the onInvoked() function checks the action property of InvokeRequest. If the property matches the string constant BB_PUSH_INVOCATION_ACTION, the function checks to see that the PushService instance is created, and that the application ID is stored. If both are true, the app extracts the push message from the invoke request by passing the invoke request into the PushPayload constructor. The pushNotificationHandler() function processes the push message.

The InvokeManager can handle the invocation when the push data is received. For demo purposes, the push messages are categorized as two different priorities to show how to handle the push messages when arrives.

// Set up InvokeManger
// ...
invokeManager = new InvokeManager(this);
	connect(invokeManager,
			SIGNAL(invoked(const bb::system::InvokeRequest&)), 
            this,
			SLOT(onInvoked(const bb::system::InvokeRequest&)));
// ...

/*
 * When the app gets invoked this method is called
 * and passed the InvokeRequest
 */
void PushManager::onInvoked(const InvokeRequest& request) {
	// Check whether the app was invoked using a push
	if (request.action().compare("bb.action.PUSH") != 0) {
		log("Not a push invocation :("); 
		return;
	}
	
	PushPayload payload(request);
	if (payload.isValid()) {
		log("payload is valid, processing now");
		if (payload.isAckRequired()) {
			log("ACK required, sending");
			m_pushService->acceptPush(payload.id());
		}
		// Read all the push data from the payload
		QString message = payload.data();
		// Pass the data to our method that stores the push in a nice format
		logPush(message);

		// For the purposes of this sample only, we expect that all push data
		// is formatted into 3 parts using a '|' character as a delimiter
		QStringList messageParts = message.split('|');
		if (messageParts.size() != 3) {
			log("Invalid list length. Expected 3, received "
                + messageParts.size());
			return;
		}

		// The first field of the push message is the priority of the message
		switch (messageParts.at(0).toInt()) {
		case PushManager::Low:
			handleLowPriorityPush();
			break;
		case PushManager::Medium:
			handleMediumPriorityPush(messageParts.at(1), messageParts.at(2));
			break;
		case PushManager::High:
			handleHighPriorityPush(messageParts.at(1), messageParts.at(2));
			break;
		default:
			break;
		}
	}
}

To receive a push message, you need to listen for navigator invoke events in your main event loop. A push message event has an action type of PUSH_INVOCATION_ACTION. You can extract the invocation data into a push_payload_t structure using push_payload_create() and push_payload_set_payload().

void handle_navigator_event(bps_event_t *event) {
     int event_type = bps_event_get_code(event);
     printf("received event type [%d]\n", event_type);
 
     switch (event_type) {
       case NAVIGATOR_EXIT:
           printf("NAVIGATOR Exit event\n");
           shutdown = true;
           break;
       case NAVIGATOR_INVOKE_TARGET: {
           const navigator_invoke_invocation_t *invoke = 
             navigator_invoke_event_get_invocation(event);
           if(invoke) {

             const char *action = 
               navigator_invoke_invocation_get_action(invoke);
             printf("Got invoke: action='%s'\n", action ? action : 
                    "NULL");

             if (strcmp(action,PUSH_INVOCATION_ACTION) == 0){

               // Get the jsonData from the invoke object and put 
               // it into a push_payload_t structure
               const unsigned char* raw_invoke_data = 
                 (unsigned char*)
                 navigator_invoke_invocation_get_data(invoke);
               int invoke_data_len =
                 navigator_invoke_invocation_get_data_
                   length(invoke);

               printf("Creating push_payload_t from 
                 raw_invoke_data\n");
               push_payload_t* push_payload;
               if(push_payload_create(&push_payload) == 
                  PUSH_FAILURE){
                  printf("failed to create push_payload. 
                   errno[%d]\n", errno);
                  return FAILURE;
                }

                if (push_payload_set_payload(push_payload,
                       raw_invoke_data, invoke_data_len) == 
                       PUSH_SUCCESS &&
                       push_payload_is_valid(push_payload)){
                     printf("push_payload_t is valid\n");
                     process_push_payload(push_payload);
                 } else {
                     printf("push_payload_t is NOT valid\n");
                 }

                 // Clean up
                 push_payload_destroy(push_payload);
                }
             }
             break;
         }
         default:
            break;
    }
 }

/* When the push message is in the push_payload_t structure,
 * retrieve the data from the structure 
 */

void process_push_payload(const push_payload_t* payload)
{
     const unsigned char* data = push_payload_get_data(payload);
     size_t data_length = push_payload_get_data_length(payload);

       printf("data length : [%d]\n", data_length);

       size_t headers_length = 
         push_payload_get_headers_length(payload);

       int i;
 
       for(i=0; i <headers_length; i++){

         const push_header_t* header = 
           push_payload_get_header(payload,i);

         if (header){
             const char* header_name = 
               push_header_get_name(header);
             const char* header_value = 
               push_header_get_value(header);

             if (header_name){
                 printf("Header name: [%s]\n", header_name);
             }

             if (header_value){
                 printf("Header value: [%s]\n", header_value);
             }
        }
    }
}

Handle notifications in the BlackBerry Hub

You can handle push message notifications in the BlackBerry Hub in the following ways:

  • When a user taps a notification in the BlackBerry Hub, your app receives an open invoke event and can display the push message that corresponds to the notification.
  • When your app receives a push message, it can add a notification to the BlackBerry Hub.
  • When a user taps the push message in your app, your app can remove the notification from the BlackBerry Hub.
  • When a user deletes an individual push message in your app, your app can remove the notification for the push message from the BlackBerry Hub.
  • When a user taps Mark All Open or Delete All in your app, your app can remove all the notifications for your app from the BlackBerry Hub.

Display a push message for an open invoke event

To receive invoke requests, your app can connect a slot to the InvokeManager invoked() signal. An open invoke request occurs when a user taps a notification for a push message in the BlackBerry Hub. You must connect to the InvokeManager signal at the beginning of the app. If you don't, your app might not receive the signal.

// Connect the InvokeManager signals and slots.

connect(m_invokeManager, 
    SIGNAL(invoked(const bb::system::InvokeRequest&)),
    this, 
    SLOT(onInvoked(const bb::system::InvokeRequest&)));

The onInvoked() function checks the action property of InvokeRequest to see if it matches the string constant BB_OPEN_INVOCATION_ACTION. If the property matches the constant, the user tapped a notification in the BlackBerry Hub. Your app can display the push message that corresponds to the notification.

void App::onInvoked(const InvokeRequest &request)
{
	if (request.action().compare(BB_OPEN_INVOCATION_ACTION) == 0){
		qDebug() << "Received open action";
		// Received an invoke request to open an existing push 
        // (that is, from a notification in the BlackBerry Hub).
		openPush(request.data().toInt());
	}
}

Add a notification to the BlackBerry Hub

The following code sample demonstrates how to create a NotificationDialog that is displayed until the user dismisses it. The notification also adds a splat indicator to the app and a notification message to BlackBerry Hub.

// Add a notification to the BlackBerry Hub 
void PushManager::handleMediumPriorityPush(const QString & title,
		const QString & body, const QString & url) {
	notification.setTitle(title);
	notification.setBody(body);

	InvokeRequest invokeRequest;
	invokeRequest.setUri(url);

	notification.setInvokeRequest(invokeRequest);
	notification.notify();
    app->setIconBadge(bb::IconBadge::Splat);
}

// Display a notification dialog
void PushManager::handleHighPriorityPush(const QString & title,
		const QString & body, const QString & url) {
	notificationDialog.cancel();
	notificationDialog.setTitle(title);
	notificationDialog.setBody(body);
	notificationDialog.setRepeat(true);
	notificationDialog.show();
}

The InvokeRequest action matches the bb.action.OPEN action and InvokeRequest MimeType matches the mime-type in the bar-descriptor.xml file. Additionally, the INVOKE_TARGET_KEY_OPEN constant has a value of com.example.pushCollector.invoke.open, which matches the invoke-target id in the bar-descriptor.xml file.

Remove a notification from the BlackBerry Hub

To remove a notification for your app from the BlackBerry Hub, call deleteFromInbox() and pass in the sequence number of the push message to remove. Your app should call this code when the user taps the trash can icon next to a push message in your app and clicks Yes in the confirmation message. Your app should delete the push message from your app.

Notification::deleteFromInbox(NOTIFICATION_PREFIX + 
    QString::number(push.seqNum()));

Remove all notifications from the BlackBerry Hub

To remove all the notifications for your app from the BlackBerry Hub, your app can call deleteAllFromInbox(). This code is called when the user taps either Mark All Open or Delete All in your app.

Notification::deleteAllFromInbox();

Accept or reject the push message

The server-side push initiator can send a confirmed push message with application-level reliability. The client-side push-enabled app must acknowledge a confirmed push message. If the server-side push initiator requires an acknowledgement for a particular push message, your client-side app can accept or reject the message.

Not applicable

// Check the isAckRequired property and acknowledge
// the receipt of the push message by accepting it 

if (payload.isAckRequired()) { 
    m_pushService->acceptPush(payload.id());
}

Situations might arise where an app might want to reject the push. For example, after looking at the headers that came with the push or the data of the push, your app might decide that the push received did not match what was expected, so you might want to reject it.

    m_pushService->rejectPush(payloadId);
 
if (push_payload_set_payload(push_payload, raw_invoke_data, invoke_data_len)
     == PUSH_SUCCESS && push_payload_is_valid(push_payload))
    {
	    printf("push_payload_t is valid\n");
	    process_push_payload(push_payload);
    } else {
	    printf("push_payload_t is NOT valid\n");
    }

// Clean up
push_payload_destroy(push_payload);

Stop the receipt of push messages

The following code sample destroys the push channel to the PPG to stop receiving push messages.

Not applicable

	m_pushService->destroyChannel();   
// When you shut down your app, you should explicitly
// deallocate any memory that was allocated for the
// push_service_t structure using push_service_cleanup().
// You also need to remove the Push Service file descriptor
// from the list monitored by BPS using bps_remove_fd().

rc = push_service_cleanup(ps);
if (rc == PUSH_FAILURE) {
	printf("push_service_cleanup: errno[%d] error[%s]\n", errno, 
	strerror(errno));
}

if (bps_remove_fd(pushPpsFd) == BPS_FAILURE){
	printf("Failed to remove PPS file descriptor\n");
}

Detect a changed SIM card

When a user changes the SIM card in a BlackBerry device, the PNS agent automatically destroys the channel and discards the push message for security reasons. A new user might be using the device, and that user shouldn't receive push messages that were intended for the previous user. To handle the SIM card change, you should authenticate all new users and create a new channel to the PPG.

Not applicable

// ...

connect(m_pushService , 
        SIGNAL (simChanged ()),  
        this,  
        SLOT (onSimChanged ()));

// ...

void PushManager::onSimChanged(){
	// Remove the currently registered user 
	// (if there is one) and unsubscribe the
	// user from the server-side push initiator
	// because switching SIMs might indicate that  
	// you are dealing with a different user. 
    // Also, remove all pushes and push
	// history from the database, and
    // call createChannel() again.
}
push_service_set_sim_change_callback(on_sim_change);

void on_sim_change(push_service_t* ps) {
	push_service_create_channel(ps, on_create_channel_complete, 
	create_channel_on_push_transport_ready);
}

Handle errors

Handling a push transport error or PPG server error

There might be occasions when your app can't create or destroy a channel because of a push transport error or a PPG server error. A push transport error occurs when there's a problem with the mobile network, the user's wireless connection, or the low-level communications layer that the Push Service uses. A PPG server error occurs when the PPG server is unavailable and returns an error. These errors don't occur if you're using the Push Service with BES10 or later.

Not applicable

// Channel operation fails. Push Service issues an error 10103
//(Transport Error) or error 10110 (PPG server error). 

void PushManager::onCreateChannelCompleted(const 
    bb::network::PushStatus &status, const QString &token){
      // ...

      QString message = tr("Create channel failed with error code: 
        %0").arg(status.code());

      Configuration config = m_configurationService.configuration();

      switch(status.code()){
        case PushErrorCode::NoError:

          // ...
        break;

        case PushErrorCode::TransportFailure:
          message = tr("Create channel failed as the push transport is 
          unavailable. "
          "Verify your mobile network and/or Wi-Fi are turned 
          on. "
          "If they are on, you will be notified when the push 
          transport is available again.");
        break;

        case PushErrorCode::SubscriptionContentNotAvailable:
          message = tr("Create channel failed as the PPG is currently 
          returning a server error. "
          "You will be notified when the PPG is available 
          again.");
        break;

      }

    sendStatusToUI(PUSH_COLLECTOR_CREATE_CHANNEL_COMPLETE, message, 
      status.code());
}

// Connect a slot to the pushTransportReady() 
// signal so that the app can create or destroy the channel

// The pushTransportReady() signal returns a 
// bb::networkPushCommand object that contains 
// the last Push Service API call that failed 
// (either CreateChannel or DestroyChannel)

PushManager::PushManager(){
    // ...
    checkConnectResult(QObject::connect(m_PushManager, 
      SIGNAL(pushTransportReady(bb::network::PushCommand::Type)),
      this, SLOT(onPushTransportReady(bb::network::PushCommand::Type))));
    // ...
}

void PushManager::onPushTransportReady(bb::network::PushCommand::Type 
  command){
      if (command == PushCommand::CreateChannel){
        m_PushManager->createChannel();
      } else {
        m_PushManager->destroyChannel();
      }
}

Not applicable

Handling a lost connection to the PNS agent

There might be rare occasions when your app loses its connection to the PNS agent running on the device. The PNS agent maintains a connection between the PPG and the app, and forwards push notifications from the PPG to the appropriate app instance.

When the app loses its connection, it can't create a session, create or destroy a channel, register to start in the background when a push message arrives, or unregister from starting in the background. When these operations fail because of the lost connection, the Push Service issues a ConnectionClosed error code.

Not applicable

// Connect a slot to the connectionClosed() signal
// to handle this error

checkConnectResult(QObject::connect(m_pushService, 
	SIGNAL(connectionClosed()),
	this, SLOT(onConnectionClosed())));

// When the connection is lost, notify the 
// user and try to re-establish the connection to
// the PNS agent

void PushManager::onConnectionClosed(){
	if (!m_timer->isActive()){
	  emit noPushServiceConnection();
	  m_timer->start(m_retryTime);
	  return;
	}
		    
	// Try to reconnect to the Push Agent
	if (!m_pushService->reconnect()){
		
	  // Reconnect was unsuccessful.
	  // If the max wait time has been reached,
	  // stop and notify the user that reconnecting 
	  // to the PNS Agent was unsuccessful.
	  // Otherwise, double the amount of time to wait
	  // before retrying, and then try again.

	  if (m_retryTime >= MAX_WAIT_TIME){
	    qWarning() << "Max number of retry attempts reached. Could 
	    not re-establish connection to Push Agent.";
	    emit pushAgentConnectionStatusChanged(false);
	    m_timer->stop();
	  } else {
	    qDebug() << "No connection to Push Agent";
	    m_retryTime = m_retryTime * 2;
	    m_timer->setInterval(m_retryTime);
	  }
	} else {
	  // Reconnect was successful.
	  // Notify the user and call createSession().
      qDebug() << "Connection to Push Agent re-established!";
	  m_timer->stop();
	  m_retryTime = INITIAL_WAIT_TIME_MILLISECONDS;
	  emit pushAgentConnectionStatusChanged(true);
	  createSession();
	}

}

// If the connection to the PNS agent is closed, the Push Service
// issues a PUSH_ERR_CONNECTION_CLOSE (501) error. Your 
// app needs to re-establish the connection with the PNS
// agent by calling push_service_get_fd() periodically until the
// function returns a valid file descriptor. You should implement
// a callback function to handle this situation.

push_service_set_connection_close_callback(ps, 
	on_connection_closed);

// The on_connection_closed() function starts a backoff timer that
// runs periodically and calls push_service_get_fd() to get a
// valid file descriptor. The interval of time between each call
// to push_service_get_fd() gets longer with each call.

void on_connection_closed(push_service_t* ps) {
	// Start backoff timer that periodically calls 
	// push_service_get_fd() until push_service_get_fd() 
	// returns a valid file descriptor.
}

Register to use the Production Push Service

When your client-side push-enabled app is ready, use the BlackBerry Push Service Production Application and Changes Form to register for the production Push Service.

If you are creating an enterprise app that sends pushes only through BES10 or BES12, you don't need to register.

When your application is approved, you receive a production Push URL in the format https://cp<your CPID>.pushapi.na.blackberry.com.

Last modified: 2017-10-12



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus