如果您的團隊在生產中使用Web3JS,那么您必須意識到Web3JS中沒有內置的重新連接功能來處理區塊鏈斷開或重新啟動, 因此,通常,當連接斷開時,NodeJS服務也需要重新啟動才能再次連接到區塊鏈,
代碼:
let hasProviderEnded = false , web3Instance, reconnectInterval = 10000 ;
var lockReconnect = false; //避免重復連接
newBlockchainConnection();
function newBlockchainConnection(){
//設定地址
let _provider=new Web3.providers.WebsocketProvider(store.state.blockchain.blockChainAddr);
hasProviderEnded = false ;
_provider.on('connect',() =>{
console.log( "區塊鏈連接成功" );
});
_provider.on( 'error' , (err) =>{
console.log("區塊鏈例外錯誤:",err.message)
});
_provider.on( 'end' , async (err) => {?
console.log( "區塊鏈連接斷開" )
???????? //處理多個end的回呼,不能重復處理,多次回呼只處理一個,
???????? if (hasProviderEnded) return ;
???????? hasProviderEnded = true ;
//重置provider的socket實體,并移除相關監聽
???????? _provider.reset();
??????? _provider.removeAllListeners( "connect" );?
?????? ? _provider.removeAllListeners( "error" );?
??????? _provider.removeAllListeners( "end" );?
???????? setTimeout( () => {
//在一段時間后發出重啟事件,以允許區塊鏈完成啟動
//我們正在另一個檔案中偵聽此事件,此回呼將初始化新連接
reconnect();
???????? }, reconnectInterval);?
});
if (web3Instance == undefined ){
web3Instance = new Web3(_provider);?
}else{
web3Instance.setProvider(_provider);
}
}
//重連
function reconnect() {
if (lockReconnect) return;
lockReconnect = true;
//沒連接上會一直重連,設定延遲避免請求過多
setTimeout(function() {
newBlockchainConnection();
lockReconnect = false;
}, 2000);
}
完全代碼:
//合約實體
import store from "@/store";
import router from '@/router';
import config from '@/config';
import Web3 from "web3";
import perpetual from '@/utils/build/contracts/Perpetual.json'
import AMM from "@/utils/build/contracts/AMM.json"
import Exchange from "@/utils/build/contracts/Exchange.json"
import ChainLink from "@/utils/build/contracts/OCRPriceConsumer.json"
import ContractReader from "@/utils/build/contracts/ContractReader.json"
import { default as contract } from 'truffle-contract';
export default class ContractUtil {
static perpetual;
static amm;
static web3;
static exchange;
static chainlink;
static contractReader;
constructor (parameter) {
this._init();
}
_init () {}
//初始化合約
static init (callback){
const _perpetual = contract(perpetual);
const _chainlink = contract(ChainLink);
const _AMM = contract(AMM);
const _Exchange = contract(Exchange);
const _ContractReader = contract(ContractReader);
// //設定地址
// let _provider=new Web3.providers.WebsocketProvider(store.state.blockchain.blockChainAddr);
// const _web3 = new Web3(_provider);
// _ContractReader.setProvider(_provider);
// _perpetual.setProvider(_provider);
// _AMM.setProvider(_provider);
// _Exchange.setProvider(_provider);
// _chainlink.setProvider(_provider);
// //掛載
// ContractUtil.perpetual = _perpetual;
// ContractUtil.amm = _AMM;
// ContractUtil.web3 = _web3;
// ContractUtil.exchange = _Exchange;
// ContractUtil.chainlink = _chainlink;
// ContractUtil.contractReader = _ContractReader;
// if(callback && typeof callback=='function'){
// callback();
// }
let hasProviderEnded = false , web3Instance, reconnectInterval = 10000 ;
var lockReconnect = false; //避免重復連接
newBlockchainConnection();
function newBlockchainConnection(){
//設定地址
let _provider=new Web3.providers.WebsocketProvider(store.state.blockchain.blockChainAddr);
const _web3 = new Web3(_provider);
_ContractReader.setProvider(_provider);
_perpetual.setProvider(_provider);
_AMM.setProvider(_provider);
_Exchange.setProvider(_provider);
_chainlink.setProvider(_provider);
//掛載
ContractUtil.perpetual = _perpetual;
ContractUtil.amm = _AMM;
ContractUtil.web3 = _web3;
ContractUtil.exchange = _Exchange;
ContractUtil.chainlink = _chainlink;
ContractUtil.contractReader = _ContractReader;
hasProviderEnded = false ;
_provider.on('connect',() =>{
console.log( "區塊鏈連接成功" );
//執行回呼
if(callback && typeof callback=='function'){
callback();
}
});
_provider.on( 'error' , (err) =>{
console.log("區塊鏈例外錯誤:",err.message)
});
_provider.on( 'end' , async (err) => {?
console.log( "區塊鏈連接斷開" )
???????? //處理多個end的回呼,不能重復處理,多次回呼只處理一個,
???????? if (hasProviderEnded) return ;
???????? hasProviderEnded = true ;
//重置provider的socket實體,并移除相關監聽
???????? _provider.reset();
??????? _provider.removeAllListeners( "connect" );?
?????? ? _provider.removeAllListeners( "error" );?
??????? _provider.removeAllListeners( "end" );?
???????? setTimeout( () => {
//在一段時間后發出重啟事件,以允許區塊鏈完成啟動
//我們正在另一個檔案中偵聽此事件,此回呼將初始化新連接
reconnect();
???????? }, reconnectInterval);?
});
if (web3Instance == undefined ){
web3Instance = new Web3(_provider);?
}else{
web3Instance.setProvider(_provider);
}
}
//重連
function reconnect() {
if (lockReconnect) return;
lockReconnect = true;
//沒連接上會一直重連,設定延遲避免請求過多
setTimeout(function() {
newBlockchainConnection();
lockReconnect = false;
}, 2000);
}
}
}
參考示例:
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?
}
文章鏈接:
我們如何處理web3js中的區塊鏈重新連接_編程故事的地方-CSDN博客
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/335244.html
標籤:區塊鏈
