Badamy procesy komunikacji warstw aplikacji elektronów, między procesem wystawcy a procesem głównym za pośrednictwem IPC. Implementujemy mechanizmy wywołujące, aby stworzyć prymitywny edytor tekstu.
W ostatnim artykule zaczęliśmy ćwiczyć mechanizmy komunikacji międzyprocesowej (IPC), które nam pomagają Pozwala na rozmowę procesom procesu głównego i procesu renderującego.
Teoretycznie wyjaśniliśmy już schemat procesu elektronowego i rolę odgrywaną przez IPC.
W tym artykule będziemy kontynuować praktykę, która już się rozpoczęła, aby wyjaśnić Jak możemy wysyłać i odbierać dane z procesu renderowania do głównego procesu elektronowego. W tym ćwiczeniu zaimplementujemy dwie operacje, które pozwolą nam zaimplementować prymitywny edytor tekstu, w którym będzie można czytać i zapisywać plik tekstowy na komputerze użytkownika.
W poprzednim artykule wywołaliśmy proces w procesie głównym, który otworzyłby plik tekstowy i wyświetlił go w terminalu wiersza poleceń procesu głównego, ale prawdopodobnie chcesz zrobić Wyślij zawartość tego pliku do interfejsu użytkownika, aby wyświetlić go w aplikacji. Chcemy również wywołać inny proces, który pozwoli nam zapisać plik tekstowy na komputerze użytkownika. Więc Prześlemy zawartość pliku tekstowego z frontendu.
Oczywiście, ponieważ jest to odczyt i zapis do folderu na dysku twardym użytkownika, musi to być wykonane z procesu nadrzędnego, a to właśnie proces ma możliwość korzystania z mechanizmów Node bez ograniczeń.
Uwzględnij kroki w celu wdrożenia tej praktyki Stwórz kilka kanałów komunikacji w IPC, gdzie wysyłamy wiadomości, gdy chcemy czytać lub pisać do pliku tekstowego. Jak dowiedzieliśmy się w poprzednim artykule, z operacji renderowania wykonujemy ipcRenderer.invoke()
Aby wywołać wiadomość w kanale wskazanym jako argument iz poziomu operacji głównej wykonujemy ipcMain.handle()
Aby wykonać akcje, gdy wiadomość dotrze do głównego procesu. Ponieważ znasz już podstawy tego procesu, jak widzieliśmy wcześniej, zaczniemy od wyjaśnienia kodu front-end, który rozpoczyna przepływ komunikacji.
kod na froncie
Na froncie mamy pole obszar tekstowy który zawiera tekst, który chcemy zapisać do pliku oraz dwa przyciski, pierwszy do pobierania zawartości pliku tekstowego i drugi do zapisywania jej po naciśnięciu.
Cały ten kod zostanie znaleziony w pliku index.html
który jest wyświetlany w oknie podczas uruchamiania aplikacji.
<form>
<label for="file">Texto:</label>
<textarea name="file" id="file" cols="30" rows="7"></textarea>
<br>
<button id="readbutton">Leer archivo</button>
<button id="savebutton">Guardar archivo</button>
</form>
Mamy wszystkie te znaczniki w formularzu, chociaż mogliśmy zapisać etykietę
<form>
Bo tak naprawdę nic byśmy z tym nie zrobili.
Programy obsługi zdarzeń są teraz widoczne dla obu przycisków, zaczynając od przycisku odczytu pliku.
document.getElementById('readbutton').addEventListener('click', function (e) {
e.preventDefault();
restoreFile();
});
Ten pierwszy przycisk po kliknięciu wywoła wywoływaną funkcję restoreFile()
I co wtedy możemy zobaczyć?
function restoreFile() {
doReadFile().then(text => document.getElementById('file').value = text);
}
Ta funkcja jest tą, która wykonuje proces Pobierz zawartość pliku tekstowego. Ten plik przyjdzie do nas z pliku główny proces Aby móc komunikować się z tym głównym procesem, będzie funkcja o nazwie doReadFile()
który zostanie wysłany z pliku preload.js
który jest wykonywany w procesie renderowania.
Musimy o tym pomyśleć doReadFile()
Jest to funkcja asynchroniczna, ponieważ dostęp do systemu plików jest asynchroniczny. zatem To, co ta funkcja zwróci, jest obietnicą. Gdy obietnica zostanie rozwiązana, otrzymana zostanie treść pliku. A wraz z nim zawartość obszaru tekstowego zostanie zaktualizowana.
Ponadto po uruchomieniu strona jest również wywoływana restoreFile()
Wyświetla zawartość pliku tekstowego w obszarze tekstowym.
restoreFile();
Zobaczmy teraz procedurę obsługi zdarzeń click
Za drugi przycisk, który wywołuje funkcję pozwalającą nam zapisać zawartość do pliku tekstowego.
document.getElementById('savebutton').addEventListener('click', function (e) {
e.preventDefault();
let text = document.getElementById('file').value;
doSaveFile(text).then(() => console.log('salvado!!') );
});
W procedurze obsługi zdarzeń po prostu uzyskujemy dostęp do zawartości pola tekstowego, a następnie wywołujemy funkcję o nazwie doSaveFile()
do którego wysyłamy tekst, który chcemy zapisać. Funkcjonować doSaveFile()
Pokazuje również obietnicę, że zostanie rozwiązany po zakończeniu zapisywania pliku tekstowego, tylko w tym przypadku nie pokazuje niczego konkretnego i po prostu wyświetlamy komunikat w konsoli przeglądarki, który mówi „uratowany!!„.
Jego celem byłoby pokazanie tej wiadomości użytkownikowi w jakiś sposób w interfejsie aplikacji, ale pozostawiamy to tobie.
Wstępnie załaduj tekst
w tekście poprzednie pobraniektóry działa w NodeJS, ale w kontekście a Proces aplikacjiW przypadku bieżącej strony istnieją funkcje, na których polegaliśmy w kodzie strony internetowej:
doReadFile().
Odpowiada za odczytanie pliku i zwrot promesy, która zostanie rozwiązana wraz z odczytaniem zawartości pliku. Widzieliśmy to już w poprzednim artykule.
contextBridge.exposeInMainWorld('doReadFile', () => ipcRenderer.invoke('readFile'));
Wiesz, używamy
contextBridge.exposeInMainWorld()
Aby ujawnić dane lub funkcje, do których możemy uzyskać dostęp później z kodu strony internetowej.
Kod funkcji nie pojawia się w tym pliku, tak jak w pliku a główny proces. Jedyne, co robimy, to tworzymy most, za pośrednictwem IPC, do tej funkcji dostępnej pod adresem Proces aplikacji z główny proces.
doSaveFile(tekst) funkcja
Ta druga funkcja pozwala nam zapisać plik. Nowością jest to, że musi otrzymać zawartość pliku, który musi napisać.
contextBridge.exposeInMainWorld('doSaveFile', (text) => ipcRenderer.invoke('saveFile', text));
Ponadto, aby przesłać te dane przez IPC do procesu nadrzędnego, użyjemy drugiego parametru metody ipcRenderer.invoke()
. Wykorzystaliśmy już pierwszy parametr, czyli nazwę kanału w IPC, z którego będziemy korzystać, a drugim parametrem są dane, które chcemy wysłać do głównego procesu.
główny proces
Teraz musimy tylko zdefiniować zachowania odczytu i zapisu w pliku tekstowym. Te zachowania wykonujemy w procesie głównym, czyli takim, który ma możliwość zaimplementowania dowolnej funkcji NodeJS.
Najpierw musimy użyć metod ipcMain.handle()
Aby ogłosić kanały komunikacji, których będziemy słuchać.
ipcMain.handle('readFile', readLocalFile);
ipcMain.handle('saveFile', saveLocalFile);
Gdy te kanały odbierają komunikaty, funkcje zostaną wywołane. readLocalFile()
I saveLocalFile()
. Piękno tych dwóch operacji polega na tym, że zwrócą one obietnice, które musimy złożyć w naszym kodzie.
W przypadku, gdy nigdy nie robiłeś metod zwracających obietnice, zostawiamy Ci link do artykułu o implementacji obietnic w javascript, z którego możesz się dowiedzieć.
Kod funkcji, która odczytuje plik, jest następujący.
let fs = require('fs');
const path = require('path');
const filePath = path.resolve('src', 'files', 'fichero.txt');
function readLocalFile() {
return new Promise( (resolve, reject) => {
fs.readFile(filePath, 'utf-8', function (err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
- Zaczynamy od zażądania modułów węzłów potrzebnych do tego zadania.
- Następnie stworzyliśmy stałą odpowiedzialną za deklarację ścieżki do pliku. Zrobiliśmy to poza funkcją, ponieważ zamierzamy użyć tej trasy do czytania i pisania.
- Wtedy mamy pracę
readLocalFile()
W tym miejscu plik jest odczytywany i zwracana jest obietnica rozpatrzona pozytywnie lub negatywnie.
Przyjrzyjmy się teraz funkcji, która zapisuje zawartość pliku tekstowego, którą nazwaliśmy saveLocalFile()
która również zwraca obietnicę, która zostanie rozwiązana, gdy ten zapis zakończy się powodzeniem lub niepowodzeniem.
function saveLocalFile(event, text) {
return new Promise((resolve, reject) => {
fs.writeFile(filePath, text, (err) => {
if(err) {
reject(err);
} else {
resolve(true);
}
});
});
}
To wszystko, co musimy zrobić dla naszej podstawowej aplikacji edytora tekstu. Nie jest to bardzo skomplikowane, jeśli rozumiemy sposób pracy z Electronem i systemem procesowym (głównym i przeglądającym), a także potrzebę wykorzystania IPC do komunikacji między nimi.
„Amatorski praktykujący muzykę. Wieloletni przedsiębiorca. Odkrywca. Miłośnik podróży. Nieskrępowany badacz telewizji.”