diff --git a/lib/tunnelbroker/tunnelbroker-context.js b/lib/tunnelbroker/tunnelbroker-context.js --- a/lib/tunnelbroker/tunnelbroker-context.js +++ b/lib/tunnelbroker/tunnelbroker-context.js @@ -125,6 +125,8 @@ const [connected, setConnected] = React.useState(false); const listeners = React.useRef>(new Set()); const socket = React.useRef(null); + const currentlyProcessedMessage = React.useRef>(null); + const socketSessionCounter = React.useRef(0); const promises = React.useRef({}); const heartbeatTimeoutID = React.useRef(); @@ -277,11 +279,30 @@ return; } const peerToPeerMessage: PeerToPeerMessage = rawPeerToPeerMessage; - void peerToPeerMessageHandler( - peerToPeerMessage, - identityClient, - message.messageID, - ); + currentlyProcessedMessage.current = (async () => { + const localSocketSessionCounter = socketSessionCounter.current; + await currentlyProcessedMessage.current; + // Since scheduling processing this message socket is closed + // or was closed and reopened, we have to stop processing + // because Tunnelbroker flushes the message again when opening + // the socket, and we want to process this only once + // to maintain order. + if ( + localSocketSessionCounter !== socketSessionCounter.current || + !socket.current + ) { + return; + } + try { + await peerToPeerMessageHandler( + peerToPeerMessage, + identityClient, + message.messageID, + ); + } catch (e) { + console.log(e.message); + } + })(); } else if ( message.type === tunnelbrokerMessageTypes.MESSAGE_TO_DEVICE_REQUEST_STATUS @@ -308,6 +329,7 @@ }; socket.current = tunnelbrokerSocket; + socketSessionCounter.current = socketSessionCounter.current + 1; } catch (err) { console.log('Tunnelbroker connection error:', err); }