Re: connection ceremony for iframe postMessage communications

On Fri, Feb 10, 2012 at 10:58 AM, Ian Hickson <ian@hixie.ch> wrote:
> On Fri, 10 Feb 2012, John J Barton wrote:
>> >
>> > What I meant was just to do this on the receiving side (inside the
>> > iframe), after the onmessage handler has been set up (which we are
>> > assuming happens after the 'load' event for some reason):
>> >
>> >   parent.postMessage('load', '*');
>> >
>> > That way you don't have to depend on the 'load' event, you can just
>> > wait for the message from the inner frame. Then when you get it, you
>> > know you can start sending..
>>
>> The problem here is that the iframe may issue parent.postMessage('load',
>> '*") before the parent onmessage handler has been set up.
>
> You can always guarantee that you've set up your handler before you create
> the iframe. But, suppose that's somehow not possible. Then you just define
> "ping" as a message you can send to the inner frame, which the inner frame
> then responds to with the aforementioned "load" message.
>
> So now you have the following situations:
>
>  - parent is set up first, then opens iframe:
>    - iframe sends 'load' message when ready
>
>  - parent opens iframe, then sets up communications, iframe is quicker:
>    - iframe sends 'load' message when ready, but it gets missed
>    - parent sends 'ping' message
>    - iframe sends 'load' message in response
>
>  - parent opens iframe, then sets up communications, parent is quicker:
>    - parent sends 'ping' message, but it gets missed
>    - iframe sends 'load' message when ready
>
> In all three cases, the first 'load' message that is received indicates
> that the communication system is ready.

Thanks. As a hint for the next person, it seems like the asymmetric
messages (parent 'ping', iframe 'load') is easier than symmetric
('hello'/'ack')

I think there are two more cases. Because the messages are all async,
the 'it gets missed case" can be "it gets delayed". That causes
additional messages.

  - parent opens iframe, then sets up communications, iframe is quicker:
   -  iframe sends 'load' message when ready, but it gets delayed
   - parent sends 'ping' message
   - parent get first 'load' message, responds with port
   - iframe sends 'load' message in response to 'ping'
 - parent opens iframe, then sets up communications, parent is quicker:
   - parent sends 'ping' message, but it gets delayed
   - iframe sends 'load' message when ready
   - iframe gets 'ping' message, sends 'load' message in response
   - parent gets 'load' message, responds with port

This doe not change your conclusion, "the first 'load' message
indicates ready", but I believe it does mean that a third message
(sending the port) is needed. The 'load' message cannot also send the
port.  It also affects when one removes the listener.


> (In practice it's usually much simpler than any of this because the parent
> can guarantee that it sets up its communications first, before the iframe
> is even created, and the child can guarantee that it sets up its
> communications before it finishes loading, so the parent can just use the
> regular 'load' event on the iframe and the child never needs to wait at
> all if it wants to start communicating first.)

Entangling communications setup with iframe 'load' just makes a
complicated problem harder, not simpler. If we can encapsulate the
above logic in a communications library then we don't have to involve
the UI or impact performance delaying load.

jjb

Received on Friday, 10 February 2012 23:45:00 UTC