Blog

Electron Communication Between Multiple Windows

Multiple Windows in Electron

The usual working of Electron is with a single window. But Electron may also work with multiple windows. There are multiple cases where that may be worthwile. For instance if you have multiple monitors, and you want each one to display a different URL.

Communication Between Two Windows via APC

Though the two windows will coexist next to each other in your code communication between these can be quite difficult to achieve. The reason for this is that each of the windows runs in its own process (called IPCRenderer). And direct communication between these is not allowed.

The two IPCRenderer processes can only communicate with the main process called IPCMain. But it seems it does not come without its quirks. Allegedly it does pass a few small objects ok. Nevertheless you'll soon reach it's limits as Electron will serialize all data passed via IPC calls.

Communication Between Two Windows via Websockets and Message Queue

This is an alternative approach which does not include internal processes. Beware if you are not aware of how websockets and message queues work, it might not be very suitable for you as it can be a bit more involved. It does work in the following manner:

First each window will open a websocket to a web server.

Second. The webserver on receiving the message will send it to a message queue.

Third. On receiving the message from the message queue, the web server sends the message to the websocket.

Fourth. The windows in Electron will listen to the websocket, and on recieving the message will take action.

Relevant code example can be seen below where the window grabs the message and appends it to a textarea.

Language: javascript
let socket = new WebSocket('ws://localhost:1880/ws/electron')

socket.onopen = function (e) {
    console.log('[open] Connection established')
    console.log('Sending to server')
    socket.send('I am connection message sent by the 1st screen')
}

 socket.onmessage = function (event) {
    let value = document.getElementById('communication').value
    value += '\r\n' + event.data
    document.getElementById('communication').value = value
}

socket.onclose = function (event) {
    if (event.wasClean) {
          console.log(
            `[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`,
          )
    } else {
        // e.g. server process killed or network down
        // event.code is usually 1006 in this case
        console.log('[close] Connection died')
    }
}

socket.onerror = function (error) {
    console.log(`[error] ${error.message}`)
}

setInterval(() => {
    socket.send('Hello from 1st screen at ' + new Date())
}, 10000)

Electron Websockets And Message Queue Diagram

As usual a visual can be quite useful, which is why a small diagram is attached below to illustrate the concept.

Starting Websocket Server in Electron with Message Relay

A wee simpler method is to only use a websocket server which is started by Electron itself before opening the multple windows. Effectively on on port Electron is serving the HTML pages, on another it opens a websocket server, all from the same Electron app. One thing to keep in mind.

Language: javascript
const WebSocket = require('ws')
const websocketServer = new WebSocket.Server({ port: 32323 })

websocketServer.on('connection', (socket) => {
  console.log('Ws Connection established')
  socket.on('message', (message) => {
    const receivedMessage = JSON.parse(message.toString())
    console.log('Message received', receivedMessage)

    // relay the message to the other paties
    websocketServer.clients.forEach(function each(client) {
      if (client !== socket && client.readyState === WebSocket.OPEN) {
        client.send(receivedMessage)
      }
    })
  })
})

This method will throw a security notice warning the end user starting the application on Windows that additional permissions are needed. It will show something in the lines of "Windows Defender Has Blocked Some Features of This App" and present an "Allow access" button to continue. In some cases it may be a small nuisance if you are an admin user, in others a show stopper if you are just a regular user.