当前位置: 首页 > 工具软件 > Web3.js > 使用案例 >

web3.js socket心跳重连,WebsocketProvider

凌照
2023-12-01

如果您的团队在生产中使用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博客

 类似资料: