Электрон: IPC против WebSocket

Для локальных приложений Node.js какой из этих двух режимов обмена данными выбрать?

Мы сравним их соответствующие функции и производительность...

Уточним, что если WebSocket доступен для всех систем на базе Node, то даже простой серверный скрипт, подобный описанному в разделе JavaScript этого сайта, IPC, когда он работает только с Electron.

На стороне сервера команды WebSocket основаны на модуле ws. Возможны и другие варианты с другими синтаксисами. Со стороны интерфейса используется стандартный объект WebSocket.

  WebSocket ИРАКСКАЯ НЕФТЯНАЯ КОМПАНИЯ
 
СЕРВЕР
Импорт const WebSocketServer = require («ws «) .Server; const {ipcMain} = require ('electron') . ipcMain
Создание коммуникационного объекта w = новый WebSocketServer (порт) -
Ожидание открытия связи w.on («соединение», (w) => {}) -
Передача данных на интерфейс w.send (данные) event.sender.send («канал», данные)
Синхронная передача данных - event.returnValue = данные
Получение данных из интерфейса w.on («сообщение», (м) => {}) ipcMain.on («канал», (e, o) => {})
Закрытие канала связи w.on («закрыть», () => {}) -
     
 
Размер ИНТЕРФЕЙСА
Импорт - const ipcRenderer = require ('electron') .ipcRenderer
Создание объекта const w = new WebSocket (порт); -
Отправка данных на сервер w.send (данные) ipcRender.send («канал», данные)
Синхронная передача данных - ipcRender.sendSyнк («канал», данные)
Получение данных с сервера w.onmessage = функция (событие) {}) ipcRender.on («канал», (событие) => {})
Закрытие канала связи w.close () -

Можно увидеть различия между двумя протоколами:

С точки зрения возможностей IPC превосходит возможность синхронного обмена данными. Не используя системные порты, он также избегает риска столкновения, когда порт уже используется другим приложением.

Демонстрация IPC

Мы построим базовое приложение с окном и бэкендом, которое общается с интерфейсом в синхронном и асинхронном режимах.

Интерфейс отправляет сообщение «hello server» на бэкенд, который отвечает через «hello интерфейс ».
В асинхронном режиме прослушиватель в интерфейсе ждет получения сообщения, на канале «сообщение».
В синхронном режиме ответ сервера - это возвращаемое значение функции, отправляющей сообщение на сервер.

Код сервера

const path = require("path")
const { app, BrowserWindow, ipcMain } = require('electron')
const print = console.log

let win
function createWindow() {
    win = new BrowserWindow({
        width: 960, height: 600, 
        title:"IPC vs. WebSocket",
        webPreferences : { nodeIntegration:true }
    })
 
    win.setMenu(null)
    const fpath = path.join(__dirname, 'ipc.html')
    win.loadURL(fpath)
    win.on('closed', () => { win = null })
}

// IPC

ipcMain.on('message', (event, data) => {
  print("Received: " + data) 
  event.sender.send('message', 'Hello interface!')
})

ipcMain.on('message-sync', (event, data) => {
  print("Received: " + data) 
  event.returnValue = 'Hello interface (synchronous)!'
})

// App

app.on('ready', createWindow)
app.on('window-all-closed', () => { 
    app.quit()
    process.exit(1)
})
app.on('quit', function () { 
    print("Done.")
})

В демо команда event.sender.send отвечает по одному и тому же каналу «сообщение», который используется при получении, но также можно отправлять данные по разным множественным каналам (в отличие от синхронного режима).

Код стороны браузера

<!DOCTYPE html>
<html>
<body>
<h1>IPC Demo</h1>
<fieldset id="storage"></fieldset>
<fieldset id="storageSync"></fieldset>
<script>
const {ipcRenderer} = require('electron')
ipcRenderer.on('message', (event, data) => {
document.getElementById("storage").innerHTML = data
})
ipcRenderer.send('message', 'Hello server!')
var answer = ipcRenderer.sendSync('message-sync', 'Hello server sync!')
document.getElementById("storageSync").innerHTML = answer
</script>
</body>
</html>

Для запуска программы введите в каталог скриптов «electron ipc.js».

Демонстрация WebSocket

Как и раньше, интерфейс отправляет сообщение «Hello server!» бэкенду, который взамен отправляет «Hello интерфейс!» в браузер .

Код сервера

Бэкэнд импортирует модуль ws, который включен в архив.

const path = require("path")
const { app, BrowserWindow  } = require('electron')
const WebSocket = require("ws")

const wss = new WebSocket.Server( { port: 1040 } )

let win
function main() {
    win = new BrowserWindow({
        width: 960, height: 600, 
        title:"WebSocket Demo"
    })
    win.setMenu(null)

    const fpath = path.join(__dirname, 'websocket.html')
    win.loadURL(fpath)
    win.on('closed', () => { win = null })
    
    wss.on('connection', function (w) {  
        w.on( 'message' , function (data)  {
             console.log(data)
        })  
        w.on('close', function() { 
             console.log("Closed") 
        })    
        w.send("Hello interface!")
    })    
}

app.on('ready', main)
app.on('window-all-closed', () => { 
    app.quit()
    process.exit(1)
})
app.on('quit', function () { 
    console.log("Done.")
})

Код стороны браузера

Интерфейс использует стандартный объект WebSocket браузера.

<!DOCTYPE html>
<html>
<body>
<h1>WebSocket Demo</h1>
<fieldset id="storage"></fieldset>
<script>
const socket = new WebSocket("ws://localhost:1040");
socket.onmessage = function(event) {
var data = event.data
document.getElementById("storage").innerHTML = data
}
socket.onopen = function() {
socket.send('Hello server!')
}
</script>
</body>
</html>

Код немного проще, потому что тестируется только асинхронный режим и на этот раз не нужно включать модуль Electron.

Введите «electron websocket.js» для запуска сценария.

Сравнительные скорости

Моим первоначальным намерением было продолжить сравнение с новыми скриптами, обменивающимися серией данных, чтобы сравнить скорость двух протоколов. Но когда ты исполнил два предыдущих сценария, видно, что это бесполезно. В то время как данные мгновенно отображаются с помощью IPC, с помощью WebSocket наблюдается заметное время.
И это нормально, IPC является внутренним для Electron, в то время как WebSocket проходит через сетевую систему компьютера, со всеми его необходимыми ограничениями и контролем.

Таким образом, с тех пор, как было принято решение использовать Electron, ИПЦ должен также стать наиболее предпочтительным способом связи, если только не требуется двусторонняя система, например уведомления с сервера.

Загрузить сценарии