Shenzhen’s weather plunged, or quite cold, we should pay attention to keep warm. Wechat official account: [Cat twelve daily], welcome to leave a message and point out question A

Last time I wrote about some methods of IPC communication, mainly the web page to the main process communication, the main process reply communication, this feeling is somewhat similar to HTTP, send an HTTP resource request, the service return a resource result, now we focus on these two points

  • The main process actively pushes messages to the Web renderer
  • Communication between Web renderers

The main process communicates actively to the renderer

This may involve a more important APi,BrowserWindow, which is used to create and control the BrowserWindow, can only be called in the main process, which is also the renderer process created by this guy

const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800.height: 600 })
win.loadURL('http://github.com')
const contents = win.webContents
console.log(contents)
Copy the code

So the webContents in Win that comes back after you create it is the API module that renders and controls web pages, we’re not going to go into that, we’re going to talk about communications

contents.send(channel, … args)

  • channelString Event name
  • . argsAny [] passes the same argument as in the previous section

Directory preparation, modification and deletion are all in these few file operations

├─ ├─ ├─ ├─ ├─ ├─ ├─ ├─ index.html // web-pageCopy the code

index.html

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Electron demo</title>
</head>

<body>Electron demo<iframe src='./other.html'></iframe>
    <script src="./renderer.js"></script>
</body>

</html>
Copy the code

renderer.js

const { ipcRenderer } = require("electron");

ipcRenderer.on("message".(event, arg) = > {
  console.log("Master into cheng elder brother, take the initiative to push the news:", arg);
});
Copy the code

main.js

const { app, BrowserWindow, ipcMain } = require("electron");
function createWindow() {
  const win = new BrowserWindow({
    width: 1920.height: 1080.webPreferences: {
      nodeIntegration: true.contextIsolation: false,}});const contents = win.webContents;
  contents.openDevTools(); // Open the debugging tool
  win.loadFile("index.html");
  contents.on("did-finish-load".() = > {
    // The callback function triggered when the page is loaded
    console.log("load");
    contents.send("message"."I saw you finished loading. I'm sending you a message.");
  });
}

app.whenReady().then(createWindow);

app.on("window-all-closed".() = > {
  if(process.platform ! = ="darwin") { app.quit(); }}); app.on("activate".() = > {
  if (BrowserWindow.getAllWindows().length === 0) { createWindow(); }});Copy the code

contents.sendToFrame(frameId, channel, … Args) sends a message via frameId to the webView embedded in the render process

  • frameId Integer | [number, number]
  • channel String
  • . args any[]

How to get the frame ID in the first place?

The first renderer actively calls the method to get the ID, and then calls the fetch method

console.log('My frameId is:'.require('electron').webFrame.routingId) // Then you pass this to the main process
Copy the code

The second main process uses a listening function to fetch it, since the renderer sends a message that triggers an event for the main process, so we can fetch it through an event

ipcMain.on('ping'.(event) = > {
  console.info('Message came from frameId:', event.frameId)
})
Copy the code

index.html

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Initial scale=1.0"> <title>Electron demo </title> </head> <body> Electron demo <webview SRC ='./other.html' </script SRC ="./renderer.js"></script> </body> </ HTML >Copy the code

main.js

const { app, BrowserWindow, ipcMain } = require("electron");
let win;
function createWindow() {
  win = new BrowserWindow({
    width: 1920.height: 1080.webPreferences: {
      nodeIntegration: true.webviewTag: true.// You need to set up the webView to enable this}});const contents = win.webContents;
  contents.openDevTools(); // Open the debugging tool
  win.loadFile("index.html");
  contents.on("did-finish-load".() = > {
    // The callback function triggered when the page is loaded
    console.log("load");
    // contents. Send ("message", "I see you finished loading, I'll send you a message");
  });
}

ipcMain.on("getFrameId".(event, arg) = > {
  console.log("FrameId received", arg); FrameId 1 was received
  console.log("Event received FrameId", event.frameId); //event Received FrameId 1
  win.webContents.sendToFrame(
    event.frameId,
    "message"."I saw you finished loading. I'm sending you a message."
  );
});

app.whenReady().then(createWindow);
app.on("window-all-closed".() = > {
  if(process.platform ! = ="darwin") { app.quit(); }}); app.on("activate".() = > {
  if (BrowserWindow.getAllWindows().length === 0) { createWindow(); }});Copy the code

other.html

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Other pages</title>
</head>

<body>
    <script>
        const {
            ipcRenderer,
            webFrame
        } = require("electron");
        ipcRenderer.send("getFrameId", webFrame.routingId);
        ipcRenderer.on("message".(event, arg) = > {
            console.log("Renderer2, the main process, tweeted:, arg);
        });
    </script>
</body>

</html>
Copy the code

renderer.js

const { ipcRenderer, webFrame } = require("electron");
console.log("My frameId is:", webFrame.routingId);

ipcRenderer.on("message".(event, arg) = > {
  console.log("Renderer2, the main process, tweeted:, arg);
});
Copy the code

The results of

Contents. PostMessage (Channel, Message, [Transfer]) uses the native Webworker to communicate

  • channel String
  • message any
  • transfer MessagePortMain[] (optional)

Write only key code, see the changes at the top for details

main.js

contents.on("did-finish-load".() = > {
    const { port1, port2 } = new MessageChannelMain();
    contents.postMessage("message"."I saw you finished loading. I'm sending you a message.", [port1]);
    port2.postMessage("I'll text you again.");
});
Copy the code

renderer.js

ipcRenderer.on("message".(event, arg) = > {
  const [port] = event.ports;
  console.log(arg, event);
  port.onmessage = (arg) = > {
    console.log(arg.data);
  };
});
Copy the code

The results of

  • I see you finished loading, send you a message Object

  • I’ll send you another message

The main process communicates with the renderer using the webContent function module

Renderers communicate with each other

ipcRenderer.sendTo(webContentsId, channel, … args)

  • webContentsIdNumber Specifies the ID of the renderer process
  • channel String
  • . args any[]

Gets the id of the renderer process

  • You can save the ID of each window when you create it
  • Or create a main process event to get the ID of each renderer

main.js

const { app, BrowserWindow, ipcMain } = require("electron");
let win;
let ids = {
  "index.html": null};function createWindow() {
  win = new BrowserWindow({
    width: 1920.height: 1080.webPreferences: {
      nodeIntegration: true.contextIsolation: false.webviewTag: true.// You need to set up the webView to enable this}});const contents = win.webContents;
  contents.openDevTools(); // Open the debugging tool
  win.loadFile("index.html");
  ids["index.html"] = contents.id;
}

ipcMain.on("registerFrameId".(event, arg) = > {
  console.log(arg);
  ids = Object.assign(ids, arg);
});

ipcMain.on("getFrameId".(event, arg) = > {
  event.returnValue = ids[arg];
});

app.whenReady().then(createWindow);
app.on("window-all-closed".() = > {
  if(process.platform ! = ="darwin") { app.quit(); }}); app.on("activate".() = > {
  if (BrowserWindow.getAllWindows().length === 0) { createWindow(); }});Copy the code

renderer.js

const { ipcRenderer } = require("electron");

onload = () = > {
  const webview = document.querySelector("webview");
  webview.addEventListener("did-finish-load".() = > {
    webview.openDevTools();
    let otherId = ipcRenderer.sendSync("getFrameId"."other.html");
    console.log(otherId);
    ipcRenderer.sendTo(otherId, "webview"."Other, buddy, have a drink.");
  });
  ipcRenderer.on("webview".(event, arg) = > {
    console.log("Message from other.html :", arg);
  });
};
Copy the code

other.html

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Other pages</title>
</head>

<body>
    <script>
        onload = () = > {
            const {
                ipcRenderer,
                remote // Get the form's unique ID from the remote module
            } = require("electron");
            // let webContent = webContents.getFocusedWebContents()
            const webContent = remote.getCurrentWebContents();
            console.log(webContent.id)
            ipcRenderer.send("registerFrameId", {
                'other.html': webContent.id
            });
            let indexId = ipcRenderer.sendSync('getFrameId'.'index.html')
            ipcRenderer.sendTo(indexId, "webview"."Index, I got a message for you.");
            ipcRenderer.on("webview".(event, arg) = > {
                document.write("Message from html.html :", arg)
            });
        }
    </script>
</body>

</html>
Copy the code

Index.html

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Electron demo</title>
</head>

<body>Electron demo<webview src='./other.html' webpreferences="nodeIntegration=true" id="webview"></webview>
    <script src="./renderer.js"></script>
</body>

</html>
Copy the code

The results of

ipcRenderer.sendToHost(channel, … args)

  • channel String
  • . args any[]

Like ipcrenderer.send, the difference is that the message is sent to the < webView > element on the host page instead of the main process

An event using the WebView listens for ‘ipC-message’ to listen for published messages

Specifically change this place

other.html

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Other pages</title>
</head>

<body>
    asdada
    <script>
        const {
            ipcRenderer,
        } = require("electron");
        ipcRenderer.on('ping'.(event, arg) = > {
            console.log("Reply from the main page", arg)
            ipcRenderer.sendToHost('message'.'Hey, buddy, I texted you.')})</script>
</body>
</html>
Copy the code

renderer.js

onload = () = > {
  const webview = document.querySelector("webview");
  webview.addEventListener("ipc-message".(event) = > {
    console.log("From webView :", event);
  });
  webview.addEventListener("did-finish-load".() = > {
    webview.openDevTools();
    webview.send("ping"."Give me a break.");
  });
};
Copy the code

The results of

To this basically the basic ipc communication method is finished, the rest is all the way to show off skills. Look at other people’s writing or their own way is still quite long, refueling

If you think my article is ok, click a like or follow the next, there are wonderful stories waiting for you oh, but also can cloud masturbation cat