I have two Node.js scripts for puppeteer automation.
1) launcher.js
This Puppeteer script launches a chrome browser and disconnects the chrome so that it can be connected by using WSEndpoint.
const puppeteer = require('puppeteer');
module.exports = async () => {
try {
const options = {
headless: false,
devtools: false,
ignoreHTTPSErrors: true,
args: [
`--no-sandbox`,
`--disable-setuid-sandbox`,
`--ignore-certificate-errors`
]
};
const browser = await puppeteer.launch(options);
let pagesCount = await browser.pages();
const browserWSEndpoint = await browser.wsEndpoint();
// console WSEndPoint say : "ws://127.0.0.1:42207/devtools/browser/dbb2525b-ce44-43c2-a335-ff15d0306f36"
console.log("browserWSEndpoint----- :> ", browserWSEndpoint);
await browser.disconnect();
return browserWSEndpoint;
} catch (err) {
console.error(err);
process.exit(1);
return false;
}
};
2) connector.js
Launches headless chrome and tries to connect chrome by WSEndPoint by various hostnames. If I ran this script with run command as node connector.js localhost
, it tries to connect WSEndpint with localhost as the hostname.
const puppeteer = require('puppeteer');
const launcher = require('./launcher');
(async (host) => {
try {
let WSEndPoint = await launcher();
WSEndPoint = WSEndPoint.replace('127.0.0.1', host);
console.log("WSENDPOINT :", WSEndPoint);
const browser = await puppeteer.connect({
browserWSEndpoint: WSEndPoint,
ignoreHTTPSErrors: true
});
let pagesCount = await browser.pages();
console.log("Pages available :> ", pagesCount.length);
// const browserWSEndpoint = await browser.wsEndpoint();
await browser.disconnect();
process.exit(1);
return true;
} catch (err) {
console.error(err);
process.exit(1);
return false;
}
})(process.argv[2]);
But I can't connect the WSEndpint of the chrome using my local IP address ( say 192.168.1.36). Why?
The error message is
{ Error: connect ECONNREFUSED 192.168.1.33:36693
at Object._errnoException (util.js:992:11)
at _exceptionWithHostPort (util.js:1014:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1186:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '192.168.1.33',
port: 36693 }
You can proxy the websocket and connect to the proxy instead. I tested it on my server and it ran successfully.
Here is how we create a websocket server using http-proxy
,
const httpProxy = require("http-proxy");
const host = "0.0.0.0";
const port = 8080;
async function createServer(WSEndPoint, host, port) {
await httpProxy
.createServer({
target: WSEndPoint, // where we are connecting
ws: true,
localAddress: host // where to bind the proxy
})
.listen(port); // which port the proxy should listen to
return `ws://${host}:${port}`; // ie: ws://123.123.123.123:8080
}
Then when we run it, we create a proxy server and listen to the ws endpoint instead. I am not exporting it to keep the explanation simpler.
// your other codes
const pagesCount = (await browser.pages()).length; // just to make sure we have the same stuff on both place
const browserWSEndpoint = await browser.wsEndpoint();
const customWSEndpoint = await createServer(browserWSEndpoint, host, port); // create the server here
console.log({ browserWSEndpoint, customWSEndpoint, pagesCount });
// your other code here
When I run on the server, we get the following,
On the droplet,
➜ node index.js
{ browserWSEndpoint: 'ws://127.0.0.1:45722/devtools/browser/df0ca6a9-48ba-4962-9a20-a3a536d403fa',
customWSEndpoint: 'ws://0.0.0.0:8080',
pagesCount: 1 }
Then we connect it like this,
const puppeteer = require("puppeteer-core");
(async serverAddr => {
const browser = await puppeteer.connect({
browserWSEndpoint: `ws://${serverAddr}`,
ignoreHTTPSErrors: true
});
const pagesCount = (await browser.pages()).length;
const browserWSEndpoint = await browser.wsEndpoint();
console.log({ browserWSEndpoint, pagesCount });
})(process.argv[2]);
On my guest computer,
➜ node index.js "123.123.123.123:8080"
Pages available :> 1
{ browserWSEndpoint: 'ws://123.123.123.123:8080' }
This way we can host on multiple server and route between them, scale away and more if needed.
Peace!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With