0

My situation is roughly this: I need to create a 'chat flow', into which users can also add self-encapsulated submodules that have their own unique, private channels to communicate on. In other words, users are chatting in chat, user #1 hits an 'add module' button, a uuid is generated and published in a 'newModule' message to the PubNub chat channel, all listeners on that channel receive the message with the uuid, and proceed to create a local copy of the module, which itself subscribes to PubNub channel 'uuid'. Module appears in chat flow, users can continue chatting, but also send (let us say) 'clicks' back and forth from the linked private modules on their own 'uuid' PubNub channels.

Unfortunately, when the new module attempt to subscribe to the new channel, PubNub 'refires' the last event received on the chat channel, triggering creation of a second, duplicate module.

I've created a stripped down test case demonstrating the problem behavior here: http://codepen.io/teolitto/pen/09f75b8b60f69a1c3aaab85af01b3cd3?editors=1000

DOM and Tag definitions:

<AppMain></AppMain>

<script type="riot/tag">
  <AppMain>
    <h3>AppMain</h3>
    <button onclick={ publishNewColorBox }>
     New ColorBox
    </button>

    //logic
    var context = this;
    context.eventBus = appCore.eventBus;

    context.publishNewColorBox = function() {
      console.log('1. "New ColorBox" button click handler')
      PN.publish({
        channel: appCore.channel,
        message: {
          type: "newColorBox",
          boxId: PN.uuid()
        }
      })
    }

    context.addNewColorBox = function(boxId){
      var cb = document.createElement('ColorBox');
      context.root.appendChild(cb);
      riot.mount(cb, {boxId: boxId});
    }

    context.init = function(){
      context.eventBus.on('addNewColorBox', function(boxId){
        console.log('3. riot "addNewColorBox" event received by application, mounting new ColorBox');
        context.addNewColorBox(boxId);
      })
    }

    context.on('mount', function(){
      context.init();
    })
  </AppMain>

  <ColorBox>
    <div></div>

    //logic
    var context = this;
    context.eventBus = riot.observable();
    context.boxId = opts.boxId;
    context.init=function(){
      console.log('4. ColorBox successfully mounted, subscribing PN to channel ',context.boxId);
      PN.subscribe({
        //channel: 'someChannel',
        channel: context.boxId,
        message: function(m){
          console.log('box channel received message:',m);
        }
      });
    }

    context.on('mount', function(){
      context.init();
    })
  </ColorBox>
</script>

Javascript:

$(function(){

  appCore = {
    channel: "firstChannel",
    eventBus: riot.observable()
  }

  PN = PUBNUB.init({
      publish_key: 'pub-c-92c890df-0f01-4f9b-9084-ec118f452dc9',
      subscribe_key: 'sub-c-e8889318-c702-11e5-837e-02ee2ddab7fe'
    });


  PN.subscribe({
    channel: appCore.channel,
    message: function(m){
      switch(m.type) {
        case "newColorBox":
          console.log('2. PN channel', appCore.channel, ' received "newColorBox" message. Firing riot event "addNewColorBox"')
          appCore.eventBus.trigger('addNewColorBox', m.boxId);
          break;
      }
    }
  });


riot.mount('AppMain');

});

I do have muxing ('stream controller') turned on in the PubNub console, so that's not it.

I've found hacks that help ameliorate the problem - setting a timeout of about 33ms before subscribing to the new channel seems to resolve the issue. If the channel being subscribed to is one that's been visited recently, the problem does not occur. However, since I need a new, unique channel every time, and I'd really really prefer to avoid a hacky solution like a timeout (god knows what else I'll run into if I have to do that), I'm asking here. Any ideas? Could this be a bug in PubNub? Or is my implementation shot?

Any input much appreciated.

HowDoIDoComputer
  • 1,383
  • 1
  • 10
  • 19
  • PubNub is not likely double publishing, but rather, the subscriber is double "pulling" the messages. I'm not sure yet the root cause, but we will investigate and report back with details. Thanks for posting. – Craig Conover Jan 31 '16 at 20:35
  • Awesome. Thanks much, Craig. – HowDoIDoComputer Jan 31 '16 at 20:43
  • Can you repost your code on codepen with non-minified pubnub lib? cdn.pubnub.com/pubnub-3.7.22.js. You could also use cdn.pubnub.com/pubnub-dev.js which points to latest JS SDK unminifed (don't use in production, of course). – Craig Conover Jan 31 '16 at 20:47
  • Hey Craig - went ahead and modified the codepen at the same link with non-minified pubnub lib - cdn.pubnub.com/pubnub-3.7.22.js. Let me know if there's anything else I can do :) – HowDoIDoComputer Jan 31 '16 at 20:51
  • Done deal - note that I had to disable auto-update so I could save the code without automatically running the app. You'll likely need to use the "run" button in codepen to run the app from hereon. Let me know if theres anything else. Thanks! – HowDoIDoComputer Jan 31 '16 at 21:32
  • Using the PubNub Dev Console, when I subscribe to firstChannel (or ch1, now), and I click *New ColorBox* button, I am only receving one message. In your app, the first two times I click it, I get 1 box (one message) and then the third time, I get 2 boxes (2 messages). So there is something going on in your code that is call your `context.addNewColorBox` function twice. Perhaps somewhere it is getting bound twice, but I am not sure just yet. I'll set this down for a bit and come back to again later today. Let me know if you make any progress though, as well. – Craig Conover Jan 31 '16 at 21:37
  • Thanks Craig - still debugging here as well. Maybe it's an issue with Riot? Seems unlikely that anything in this simple app is double binding (I've checked for that about a dozen times), but I'm still digging - I'll let you know if I find anything. – HowDoIDoComputer Jan 31 '16 at 21:51
  • Curiously, (I have forked the app and am running on 'ch1B') when I click the "New ColorBox" button, I get 2 boxes right off the bat, and continually thereafter. It seems you are seeing intermittent behavior between 1 and 2 boxes - this seems to support a race condition, which is perhaps also suggested by the 100ms timeout resolving the issue... Interestingly, it's also the case that if I change the uuid to a previously visited channel (uncomment line 53 and comment line 54), the issue does not occur...in other words, if you set the second channel name to something fixed, you'll see the issue – HowDoIDoComputer Jan 31 '16 at 21:57
  • the first load, but if you refresh the page and subsequently click the "New ColorBox" button, you'll see that the issue no longer appears... – HowDoIDoComputer Jan 31 '16 at 22:00
  • Made some progress - not sure if you already tried this but if you comment out your subscribe to the UUID channel, the problem goes away. Continuing to debug. – Craig Conover Feb 01 '16 at 00:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/102185/discussion-between-craig-conover-and-howdoidocomputer). – Craig Conover Feb 01 '16 at 01:19
  • How was this resolved? I am getting multiple (duplicate) event handler calls and [**can't figure out why**](http://stackoverflow.com/questions/42440256/pubnub-angularjs-service-fires-repeatedly). – lilbiscuit Feb 24 '17 at 21:25

0 Answers0