IPC (Inter-Process Communication) в контексте Quasar используется преимущественно для взаимодействия между основным процессом Electron и рендерером Vue-компонентов. Это ключевой механизм, обеспечивающий безопасный и эффективный обмен данными между процессами.
В Quasar IPC реализуется через модуль electron и
стандартный API Electron: ipcMain и
ipcRenderer. Основной принцип работы — рендерер отправляет
сообщение в главный процесс, который обрабатывает его и возвращает
результат.
// main process (main.js)
const { ipcMain } = require('electron');
ipcMain.handle('get-data', async (event, args) => {
// Логика получения данных
const data = await fetchDataFromDatabase(args);
return data;
});
// renderer process (Vue компонент)
const { ipcRenderer } = window.require('electron');
async function fetchData() {
const result = await ipcRenderer.invoke('get-data', { userId: 123 });
console.log(result);
}
Использование метода ipcMain.handle вместе с
ipcRenderer.invoke позволяет работать с асинхронными
операциями, обеспечивая удобный и безопасный обмен данными.
ipcRenderer.send(channel, ...args) –
отправляет сообщение в главный процесс без ожидания ответа.ipcRenderer.invoke(channel, ...args) –
отправляет сообщение и ожидает асинхронного ответа от
ipcMain.handle.ipcRenderer.on(channel, listener) –
подписка на события, приходящие из главного процесса.ipcMain.on(channel, listener) –
обработка событий из рендерера без возврата значения.ipcMain.handle(channel, listener) –
обработка вызовов с асинхронным возвратом значения.Разделение на send/on и invoke/handle
позволяет выбирать между однонаправленным сообщением и полноценным
асинхронным запросом с результатом.
Для упрощения поддержки рекомендуется:
user:*, file:*, settings:*).// channels.js
export const CHANNELS = {
USER_GET: 'user:get',
USER_UPDATE: 'user:update',
FILE_READ: 'file:read'
};
// main.js
ipcMain.handle(CHANNELS.USER_GET, async (event, userId) => {
return getUserFromDb(userId);
});
// renderer.vue
const user = await ipcRenderer.invoke(CHANNELS.USER_GET, 42);
Такой подход повышает читаемость и поддерживаемость кода.
Поскольку рендерер работает в пользовательском контексте, необходимо ограничивать прямой доступ к Node API. В Quasar это делается с использованием preload скриптов:
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('api', {
getUser: (userId) => ipcRenderer.invoke('user:get', userId)
});
В рендерере теперь доступно:
const user = await window.api.getUser(42);
Это предотвращает злоупотребления и обеспечивает безопасный мост между процессами.
IPC подходит не только для запросов, но и для событийной коммуникации:
// main.js
ipcMain.on('file:changed', (event, filePath) => {
console.log(`Файл изменен: ${filePath}`);
});
// renderer.vue
ipcRenderer.send('file:changed', '/path/to/file.txt');
Для обратной связи из главного процесса используется
event.reply или отдельный канал:
// main.js
ipcMain.on('start-process', (event) => {
const result = runLongTask();
event.reply('process:done', result);
});
// renderer.vue
ipcRenderer.on('process:done', (event, result) => {
console.log('Процесс завершен:', result);
});
Такой подход позволяет организовать полноценное событие-ориентированное взаимодействие между процессами.
ipcMain.handle, чтобы
рендерер получал корректные ответы.Эти сценарии демонстрируют универсальность IPC и его критическую роль в архитектуре Quasar с Electron.