In this article, we’ll learn how to handle blockchain disconnects in the production environment automatically, using Web3JS. The method described below works for Web3JS version 1.0.0-beta.35, but it should be good for the stable 1.2.* versions as well.
If your team uses Web3JS in production, then you must be aware that there’s no inbuilt reconnect functionality in Web3JS to handle blockchain disconnects or restarts. So, usually, when there is a connection drop, NodeJS service needs to be restarted as well to connect to the blockchain again. Not a very practical approach.
Let’s see how we can gracefully handle blockchain disconnects in NodeJS. In the Web3JS library, the Provider object gives us events for
Upon disconnection, we can utilize the end event to reinitiate a new Web3JS connection. Let’s look at an example to understand this:
In this file, we’ll handle the connection between NodeJS and blockchain. We will have a newBlockchainconnection method which will return a Web3 active connection object.
const web3 = require("web3");
let hasProviderEnded = false, web3Instance, reconnectInterval = 10000;
async function newBlockchainConnection(webSocketProvider, endCallback) {
// create new provider
const provider = new web3.providers.WebsocketProvider(webSocketProvider);
hasProviderEnded = false;
// connect event fires when the connection established successfully.
provider.on('connect', () => console.log("connected to blockchain"));
// error event fires whenever there is an error response from blockchain and this event also has an error object and message property of error gives us the specific reason for the error
provider.on('error', (err) => console.log(err.message));
// end event fires whenever the connection end is detected. So Whenever this event fires we will try to reconnect to blockchain
provider.on('end', async (err) => {
// handle multiple event calls sent by Web3JS library
if (hasProviderEnded) return;
// setting hashProviderEnded to true as sometimes the end event is fired multiple times by the provider
hasProviderEnded = true;
// reset the current provider
provider.reset();
// removing all the listeners of provider.
provider.removeAllListeners("connect");
provider.removeAllListeners("error");
provider.removeAllListeners("end");
setTimeout(() => {
// emitting the restart event after some time to allow blockchain to complete startup
// we are listening to this event in the other file and this callback will initialize a new connection
endCallback();
}, reconnectInterval);
});
if (web3Instance == undefined) web3Instance = new web3(provider);
else web3Instance.setProvider(provider);
return web3Instance;
}
module.exports = {
newBlockchainConnection
}
const connection = require("connection");
const web3JSConnection;
const endCallback = async function () {
web3JSConnection = await connection.newBlockchainConnection('ws://127.0.0.1:8545', customEvent);
});
async function getWeb3Connection() {
if (web3JSConnection == undefined) web3JSConnection = await connection.newBlockchainConnection('ws://127.0.0.1:8545', endCallback);
return web3JSConnection;
}
module.exports = {
getWeb3Connection
}
On blockchain disconnection, when the provider triggers the ‘end’ event, we are triggering a callback after a timeout. The event then, in turn, calls the function to create a new blockchain connection.
Some points to note:
Many technology-first companies like Skeps are developing a revolutionary product using blockchain. Stay tuned till our next write-up on this new-age technology.
https://skeps.com/blog/how-we-handle-blockchain-reconnects-in-web3js