Электрон: 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 и по одному для каждого окна в интерфейсе. Мы взаимодействуем с окном, указывая название канала.
Для WebSocket именно номер порта отличает точки связи. - IPC имеет синхронный режим, а не WebSocket.
- Но второе - двунаправленное: сервер может запустить обмен данными .
С точки зрения возможностей 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, ИПЦ должен также стать наиболее предпочтительным способом связи, если только не требуется двусторонняя система, например уведомления с сервера.
Загрузить сценарии