<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
     var received = [];
     window.addEventListener('message', function (message) {
       var data;
       if (typeof message.data === 'string') {
         data = JSON.parse(message.data);
       } else {
         data = message.data;
       }
       if (!data.protocol || !data.command) {
         return;
       }
       data.origin = message.origin;
       received.push(data);
     });
     window.handleProtocolMessage = function (callback) {
       if (!received.length) {
         callback(null);
       }
       var msg = received.shift();
       callback(msg, function (protocol, command, payload) {
         console.log("SEND", protocol, command, payload, msg.origin);
         window.parent.postMessage(JSON.stringify({
           protocol: protocol,
           command: command,
           payload: payload
         }), msg.origin);
       });
     };
     window.clearMessages = function () {
       received = [];
     };
    </script>
  </body>
</html>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <script>
     var received = [];
     window.addEventListener('message', function (message) {
       var data;
       if (typeof message.data === 'string') {
         data = JSON.parse(message.data);
       } else {
         data = message.data;
       }
       if (!data.protocol || !data.command) {
         return;
       }
       received.push(data);
     });
     window.sendProtocolMessage = function (protocol, command, payload) {
       // Simulate some network delay
       setTimeout(function () {
         window.parent.postMessage(JSON.stringify({
           protocol: protocol,
           command: command,
           payload: payload
         }), window.parent.location.href);
       }, Math.ceil(Math.random() * 10));
     };
     window.handleProtocolMessage = function (callback, retried) {
       if (!received.length) {
         if (!retried) {
           setTimeout(function () {
             window.handleProtocolMessage(callback, true)
           }, 10);
           return;
         }
         callback(null);
         return;
       }
       var msg = received.shift();
       setTimeout(function () {
         callback(msg, window.sendProtocolMessage);
       }, 1);
     };
     window.clearMessages = function () {
       received = [];
     };
    </script>
  </body>
</html>

Add timeouts to simulate network latency
Add timeouts to simulate network latency
