How to use PubNub publish callback to find out which message to re-publish in case of an error
Asked Answered
W

3

8

The publish callback in PubNub API returns with a message like below -

[1,"Sent","13729639808030640"]

But this does not give any indication as to for which message this callback is for. In case of publish error, the first value in the return array will be 0. But how do you find out which message to re-publish?

The publisher can be publishing messages at a high rate and not waiting to receive the callback before publishing another message. So when the callback is invoked the publisher might have already published 10 more messages.

Watusi answered 4/7, 2013 at 19:5 Comment(4)
Good question and you'll want to set this up on many different ways. Also it depends on which SDK you are using.Chirk
i know this is an old question but it's not yet answered by @PubNub and i'm having the same dilemma as of the moment. I'm on android but the platform should not matter.Crural
Is first-in, first-out tracking acceptable for you @Crural ? The responses, error or not, will never come out of order.Voelker
If the "responses, error or not will never come out of order" is 100% reliable, then yeah. creating a queue for pending messages is the way to go to i think. But i'd like to confirm with you if this is the best practice for pubnub in terms of keeping track of pending messages.Crural
H
3

PubNub REST API provide JSONP format as well. You can create map of "callback function" identifiers to actual messages and when processing completed, you can obtain reference on original message using "callback function" identifier from response.
For example:

https://pubsub.pubnub.com/publish/demo/demo/0/iosdev/m_2c453/%22Hello%20world2%22  

As you can see, there is m_2c453 in URI, it will be used by server in response:

m_2c453([1,"Sent","14034711347326358"])

And here we know, that m_2c453 has been used to send "Hello world" message.
But, I think platform dependent PubNub SDK should handle all this for you.

Horne answered 22/6, 2014 at 21:7 Comment(2)
Also, keep in mind, even if you rapid fire publishes, all responses will come back from the server in the order they were issued... you'll never get an out-of-order response on the same connection you published on.Voelker
thank you for your quick response,as mentioned, I'm using the android sdk and it only returns the JSONArray message and not the one with the jsonp format. how do you do that in android?Crural
C
0

Transferred here since it's too long for a message reply.

In reply with @Geremy, so if message 1,2,3,4,5 will be sent, i'll get a publish callback in 1,2,3,4,5 order? there won't be a case where a response will fail in say 2 and 4? In that case, if we'll continue in the notion that we get an ordered response, this would mean that a response failed to arrive for messages 4 and 5 instead of 2 and 4. Might I suggest to the pubnub team that they add a fourth data in the JSONArray they return, it would contain the id field in the message that was published ( if there is such a data e.g. { "id":123, message:"hello"} ), if there's is none, obviously the returned id would be null or empty string.

Crural answered 23/6, 2014 at 3:12 Comment(3)
Yes, you should get back the responses (good or bad) in the order they were sent.Voelker
So maintaining a pending message queue and dequeing when a publish callback is called would keep track pending messages.Crural
you should really emphasize this on your documentation since this is a very important feature, and an obvious one to have.Crural
M
0

I faced a similar challenge. I wanted to queue messages while the device is offline, and then send them on reconnect. In the callback i needed a way of knowing which message was sent to remove it from the queue. I came up with this solution:

function sendData(channel, data, callback) {
  Pubnub.publish({
    channel: channel,
    message: data,
    callback : callback
  });
}

//This code is placed within the "reconnect" callback of the subscription
if ($localStorage.chatQueue.length) {
  for (var i = 0; i < $localStorage.chatQueue.length; i++) {
    sendData(
      $localStorage.chatQueue[i].channel,
      $localStorage.chatQueue[i].data,
      function(){
        console.log("arguments");
        console.log(arguments);
        console.log("this");
        console.log(this);
        index = $localStorage.chatQueue.indexOf(this);
        console.log("Message in offline queue sent, index = "+index);
        if (index > -1) {
          $localStorage.chatQueue.splice(index, 1);
        }
      }.bind($localStorage.chatQueue[i])
    );
  }
}

The trick is binding this in the callback function to the message object. It seems to work. I guess one could also just bind the i variable which would give a direct pointer to the message in the queue.

I was inspired by this answer in another question: https://mcmap.net/q/481309/-how-to-pass-context-to-anonymous-function

Me answered 13/1, 2017 at 9:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.