Using MessageChannel() bidirectionally for multiple messages between page and iframe

前端 未结 1 1572
庸人自扰
庸人自扰 2021-01-01 07:36

I\'m using MessageChannel() to pass messages between a page and iframe. In my scenario, the iframe is the communications initiator and the page containing it receives, trans

相关标签:
1条回答
  • 2021-01-01 08:26

    That's not really clear what you are doing, even reading your code on github...

    You seem to be confusing the WindowObject.postMessage method and the MessagePort's one. WindowObject's one should be used only once, at the negotiation part.
    So let's take a step back to explain more basically how things should be understood:


    You should think of message channels as a Yoghurt-pot Telephone® [pdf].

                       –––––                         –––––
                    po(r)t1 |~~~~~~~~~~~~~~~~~~~~~~~| po(r)t2
                       –––––                         –––––
    
    • One user has to create it.
    • Then he will give (transfer) one of the po(r)ts to the other user.
    • Once this is done, each user has only access to its own po(r)t.
    • So to be able to receive messages from the other user, they have to put their ear on their own po(r)t (attach an event handler).
    • And to send messages, they will say the message (postMessage) inside the only po(r)t they still have, the same they are listening to.

    So to add some lines of code, what you should do is:

    1. Generate The Yoghurt-pot telephone® a.k.a MessageChannel.

      var yoghurt_phone = new MessageChannel();
      
    2. Keep one of the po(r)t and give the other one to the other user (iframe). To do this, we use the WindowObject.postMessage method, which is not the same as the one we'll use to communicate through the MessagePorts.

      mains_yoghurt_pot = yoghurt_phone.port1;
      frame.contentWindow.postMessage( // this is like a physical meeting
        'look I made a cool Yoghurt-phone', // some useless message
        '*', // show your id?
        [yoghurt_phone.port2] // TRANSFER the po(r)t
      ); 
      
    3. From the frame, receive the po(r)t and keep it tight.

      window.onmessage = function physicalMeeting(evt) {
        if(evt.ports && evt.ports.length) { // only if we have been given a po(r)t
          frames_yoghurt_pot = evt.ports[0];
          // ... 
      
    4. From now on, each user has its own po(r)t, and only a single po(r)t. So at both ends, you need to setup listeners on their own single po(r)t.

      // from main doc
      mains_yoghurt_pot.onmessage = frameTalksToMe;
      

      // from iframe doc
      frames_yoghurt_pot.onmessage = mainTalksToMe;
      
    5. And then when one of the two users wants to tell something to the other one, they'll do from their own po(r)t.

      // from main doc
      mains_yoghurt_pot.postMessage('hello frame');
      

      // or from iframe doc
      frames_yoghurt_pot.postMessage('hello main');
      

    Fixed OP's code as a plunker.

    0 讨论(0)
提交回复
热议问题