JavaScript Hintergrundprozess laufen lassen?
Ich möchte eine JavaScript Aufgabe asynchron im Hintergrund laufen lassen, die vom Client gesteuert wird.
Normalerweise wird eine asynchrone Aufgabe ausgeführt und gibt eine Antwort zurück.
Ich allerdings möchte den Hintergrundprozess laufen lassen und immer wieder Antworten bekommen.
In meinem Beispiel ist es Puppeteer, eine Alternative für Selenium.
Auf der Website läuft der Puppeteer Browser auf dem Server. Clientseitig soll dieser Hintergrundprozess gesteurt werden, zum Beispiel klickt der Client einen Button, der im Puppeteer Browser auf dem server etwas auslöst.
Wie kann ich so einen Hintergrundprozess, Puppeteer, laufen lassen?
Ich bin es gewohnt, nur sowas wie API-Endpunkte zu benutzen, also eine Anfrage wird gesendet, die Aufgabe wird ausgeführt und eine Antwort kommt zurück.
2 Antworten
Wozu dauerhaft laufen lassen? Du sagst, der Client drückt einen Button, und dann soll im Browser auf dem Server etwas passieren. Du kannst doch in der Sekunde, wo die Anfrage des Clients rein kommt, den Browser starten.
Den Browser dauerhaft laufen lassen würde nur Sinn machen, wenn manche Client Requests von vorherigen abhängen (die Seite im Browser also dauerhaft laufen muss), oder das Starten des Browsers ziemlich lange dauert. In dem Fall würde ich wahrscheinlich zu WebSockets via socket.io greifen.
In Node.js initialisiert du in der main.js (oder wie auch immer deine Startdatei heißt) eine "globale" Puppeteer-Instanz mittels puppeteer.launch(). Sobald der Browser gestartet wurde, startest du einen socket.io Server. Mit diesem kommuniziert dann der Client. Wenn der Client also über socket.io einen Befehl X gibt, kannst du auf dem Server damit den Browser steuern.
Wenn es unbedingt eine REST API und kein WebSocket Server sein muss, geht das im Prinzip genauso: Eine globale Puppeteer-Instanz initialisieren und den Express-Routen (oder welches Framework man auch immer nimmt für die REST API) diese als Parameter übergeben.
Solang der WebSocket (oder Express) Server läuft, bleibt auch die Puppeteer-Instanz offen.
Die socket.io Variante grob zusammen geschustert (keine Garantie für Funktionalität):
const server = require('http').createServer();
const io = require('socket.io')(server);
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://somepage.com');
io.on('connection', client => {
client.on('event', data => {
page.type('.some-field', 'Some text')
});
/* ... */
});
server.listen(3000);
})();
Events + Event handler?
Ansonsten können Worker so was.
Manche Client requests hängen vom vorherigen ab