Home > Mobile >  What is the practical usages of MessagePorts in electron Js?
What is the practical usages of MessagePorts in electron Js?

Time:04-07

what is the practical usages of MessagePorts in electron Js? why we need this? instead can't we use ipcRenderer.invoke? I can't see any practical usages of MessagePorts. It's just data transfering between main process and renderer process like ipcRenderer.invoke and ipcMain.handle. Can you tell me a practical problem that can only be solved with MessagePort and can't be solve by ipcRenderer.invoke and ipcMain.handle?

CodePudding user response:

As you know, Electron's IPC functions are used to communicate between the main process and render process(es), either one way ipcMain.on(channel, listener)(render -> main) or reply ipcMain.handle(channel, listener) (render -> main -> render).

Electron's MessagePorts serve a slightly different purpose. Instead of communicating between the main and render processes, it communicates between the main process and your render iframe.

The source code of the iframe would be configured to listen for messages from the main process and send messages back to the main process.

To quote MDN Web Docs - Channel Messaging API

The Channel Messaging API allows two separate scripts running in different browsing contexts attached to the same document (e.g., two IFrames, or the main document and an IFrame, two documents via a SharedWorker, or two workers) to communicate directly, passing messages between one another through two-way channels (or pipes) with a port at each end.

Though based on webpage to iframe communication, the Examples section of the above quoted document gives two great examples, a simple static example and more dynamic example.

For sake of prosperity, I have copied and pasted a stripped down version of the dynamic example code so you can better understand the concepts and design.

index.html (main page)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Channel messaging demo</title>
      </head>

    <body>
        <h1>Channel messaging demo</h1>
        <p id="message-output">Message not yet sent</p>

        <form>
            <label for="message-input">Send a message</label>
            <input type="text" id="message-input" autofocus>
            <button>Send Message</button>
        </form>

        <iframe src="page2.html" width='480' height='320'></iframe>
    </body>

    <script>
        var input = document.getElementById('message-input');
        var output = document.getElementById('message-output');
        var button = document.querySelector('button');
        var iframe = document.querySelector('iframe');
        var channel = new MessageChannel();
        var port1 = channel.port1;

        // Wait for the iframe to load
        iframe.addEventListener("load", onl oad);
    
        function onl oad() {
            // Listen for button clicks
            button.addEventListener('click', onClick);

            // Listen for messages on port1
            port1.onmessage = onMessage;

            // Transfer port2 to the iframe
            iframe.contentWindow.postMessage('init', '*', [channel.port2]);
        }

        // Post a message on port1 when the button is clicked
        function onClick(e) {
            e.preventDefault();
            port1.postMessage(input.value);
        }

        // Handle messages received on port1
        function onMessage(e) {
            output.innerHTML = e.data;
            input.value = '';
        }
    </script>
</html>

page2.html (iframe)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>My page title</title>
    </head>

    <body>
        <ul></ul>
    </body>

    <script>
        var list = document.querySelector('ul');
        var port2;
    
        // Listen for the intial port transfer message
        window.addEventListener('message', initPort);

        // Setup the transfered port
        function initPort(e) {
            port2 = e.ports[0];
            port2.onmessage = onMessage;
        }

        // Handle messages received on port2
        function onMessage(e) {
            var listItem = document.createElement('li');
            listItem.textContent = e.data;
            list.appendChild(listItem);
            port2.postMessage('Message received by IFrame: "'   e.data   '"');
        }
    </script>
</html>

A useful example of using ports with Electron - You have a URL loaded within an iframe and your application needs to interact with it, such as transferring data between your application and the external site (via ports) or the external site needs to return data when queried (via ports). I guess it could be compared to a simplistic API if such functionality was needed.

To read more about the use of ports in electron, see MessagePorts in Electron. Within this document, the heading titled MessagePorts in the main process is what should bring this concept home for you.

  • Related