FreeRTOSFreeRTOSWindows CmbedPosix CCFreeRTOS Storage & Playback Tutorial for Realtime Apps

Requires that the Storage and Playback add-on is enabled for your key. How do I enable add-on features for my keys? - see http://www.pubnub.com/knowledge-base/discussion/644/how-do-i-enable-add-on-features-for-my-keys
PubNub's Storage and Playback feature enables developers to store messages as they are published, and retrieve them at a later time. Before using this feature it must be enabled in the PubNub Admin Console.
Being able to pull an archive of messages from storage has many applications:
  • Populate chat, collaboration and machine configuration on app load.
  • Store message streams with real-time data management.
  • Retrieve historical data streams for reporting, auditing and compliance (HIPAA, SOX, Data Protection Directive, and more).
  • Replay live events with delivery of real-time data during rebroadcasting.
As needed, specific messages can be marked "do not archive" when published to prevent archiving on a per-message basis, and storage retention time can range from 1 day to forever.
These code samples build off code defined in the Pub & Sub tutorial, so before proceeding, be sure you have completed the Pub & Sub tutorial first.
To begin, lets populate a new channel with some test publishes that we'll pull from storage using the pubnub_history() method.

We'll define a callback for response handing that is applicable for both pubnub_publish() and pubnub_history() methods.
//Sync Example
 
#define BUFFER_SIZE 14
 
const char *channel = "history_channel";
const char *message_tmp = "\"message#%d\"";
char buffer[BUFFER_SIZE];
enum pubnub_res res;
int i;
 
for (i = 0; i < 500; i++) {
  snprintf(buffer, BUFFER_SIZE, message_tmp, i);
  pubnub_publish(pn, channel, buffer);
  res = pubnub_await(pn);
 
  if (PNR_OK != res) {
    break;
  }
}
 
 
// Callback Example
#define BUFFER_SIZE 14
struct UserData {
    int message_id;
}; 
void start_publish_500_messages(pubnub_t *pn, struct UserData *pData) {
  const char *channel = "history_channel";
  enum pubnub_res res;
  pData->message_id = 0;
}
int receive_publish_500_message(pubnub_t *pn, struct UserData *pData, enum pubnub_res res) {
    const char *channel = "history_channel";
    if (PNR_OK != res) {
      return -1;
    }
    if (pData->message_id < 500) {
      char msg[BUFFER_SIZE];
      ++pData->message_id;
      snprintf(msg, sizeof msg, “\”message%d\”, pData->message_id);
      pubnub_publish(pn, channel, msg);
    }
    return 0;
}
Before we can pull history for a channel, that channel must first have had messages published on it. We'll do just that by publishing some messages onto a channel to "seed" it for a history call.
//Sync Example

#define BUFFER_SIZE 14

const char *channel = "history_channel";
const char *message_tmp = "\"message#%d\"";
char buffer[BUFFER_SIZE];
enum pubnub_res res;
int i;

for (i = 0; i < 500; i++) {
  snprintf(buffer, BUFFER_SIZE, message_tmp, i);
  pubnub_publish(pn, channel, buffer);
  res = pubnub_await(pn);

  if (PNR_OK != res) {
    printf("Publishing #%d failed with code: %d\n", i, res);
    break;
  }
}


// Callback Example
#define BUFFER_SIZE 14

void publish_500_messages(pubnub_t *pn) {
  const char *channel = "history_channel";
  const char *message_tmp = "\"message#%d\"";
  char buffer[BUFFER_SIZE];
  enum pubnub_res res;
  int i;

  pubnub_register_callback(pn, sample_callback);

  for (i = 0; i < 500; i++) {
    snprintf(buffer, BUFFER_SIZE, message_tmp, i);
    pubnub_publish(pn, channel, buffer);
    printf("Publishing #%d...", i);

    res = await(&user_data);
    if (PNR_OK != res) {
      printf(" Publishing #%d failed with code: %d\n", i, res);
      break;
    }

    printf(" OK\n");
  }
}
In the above example, we publish a barrage of test messages to history_channel.
Now that we've populated the channel (and thus the backend storage system), we can pull from storage using the pubnub_history() method call:
// Sync
enum pubnub_res res;
const char *msg;
   
pubnub_history(pn, "history_channel", 10, false);
res = pubnub_await(pn);
if (PNR_OK == res) {
  for (;;) {
    msg = pubnub_get(pn);
    if (NULL == msg) {
      break;
    }
    // Print out, on Window simulator, `puts(msg)` should work
  }
} else {
}
   
   
// Callback
void start_get_last_10_messages(pubnub_t *pn) {
  enum pubnub_res res;
  const char *msg;
   
  pubnub_history(pn, "history_channel", 10, false);
}
 
void receive_last_10_messages(pubnub_t *pn, enum pubnub_res res) {
 
  if (PNR_OK == res) {
    for (;;) {
      msg = pubnub_get(pn);
      if (NULL == msg) {
        break;
      }
    // Print out, on Window simulator, `puts(msg)` should work
    }
  } else {
     return -1;
  }
  return 0;
}
The response format is
[
	["message1", "message2", "message3",... ],
	"Start Time Token",
	"End Time Token"
]
The timetoken response value is a string, representing 17-digit precision unix time (UTC). To convert PubNub's timetoken to Unix timestamp (seconds), divide the timetoken number by 10,000,000 (10^7).