【问题标题】:Why Does My Ethereum ".on" Event Listener Stop Firing?为什么我的以太坊“.on”事件监听器停止触发?
【发布时间】:2022-01-16 09:54:40
【问题描述】:

我有一个 node.js 服务器,我在其中监听从部署在 Mumbai Polygon 测试网上的 Solidity 智能合约发出的事件。

首先,我使用“web3-providers-ws”节点包创建提供程序,使用 keepalive 和重新连接选项:

let providerNetworkUrl;
let ccggContractAddress;

if (process.env.TESTNET === 'true') {

  console.log('using mumbai URLs')
  // on mumbai
  ccggContractAddress = process.env.CCGG_ADDRESS_MUMBAI_TESTNET;
  providerNetworkUrl = 'wss://polygon-mumbai.g.alchemy.com/v2/';
} else {
  // on polygon mainnet
  ccggContractAddress = process.env.CCGG_ADDRESS_POLYGON_MAINNET;
  providerNetworkUrl = 'wss://polygon-mumbai.g.alchemy.com/v2/';
}

const connectionUrl = providerNetworkUrl + process.env.alchemyApiKey;
console.log('connectionUrl: ', connectionUrl)

// Enable auto reconnection
const options = {

  clientConfig: {
    // Useful to keep a connection alive
    keepalive: true,
    keepaliveInterval: 20 * 60 * 60 * 1000 // keep alive for 20 min
  },

  // Enable auto reconnection
  reconnect: {
    auto: true,
    delay: 1000, // ms
    maxAttempts: 10,
    onTimeout: false
  }
};

let provider = new ethers.providers.WebSocketProvider(
  new Web3WsProvider(connectionUrl, options))

provider.on('end', (e) => {
  console.log('provider ended: ' + e);
})

provider.on('error', (e) => {
  console.log('provider errored: ' + e);
})

然后我使用 ethers.js 连接到智能合约。

const wallet = new ethers.Wallet(process.env.PRIVATE_WALLET_KEY, provider)
console.log('my address (wallet): ', wallet.address)

const signer = wallet.connect(provider)

const ccggContract = new ethers.Contract(
  ccggContractAddress,
  ccggAbi,
  signer
)

最后我为“GuessSubmitted”事件设置了监听器。

ccggContract.on('GuessSubmitted', async (guess, sender, betSize) => {

  console.log('GuessSubmitted')

})

奇怪的是,当我第一次启动它时,一切都很好。节点服务器听到事件,记录“GuessSubmitted”,并处理事件。

但是,几个小时后,或者一夜之间,我去玩游戏,事件在 Solidity 中调度,但节点服务器什么也没听到!!!什么??

在查看了互联网上的其他一些帖子后,我什至设置了这个 ping 函数来保持 websocket 连接处于活动状态,并且我每 15 分钟调用一次:

async function ping() {

  const now = new Date();

  try {
    console.log('Sending a ping! ' + now.toUTCString());
    const blockNum = await provider.send('eth_blockNumber');
    console.log('Got blocknum: ', blockNum);
  }
  catch (err) {
    console.log('PING ERROR')
    console.log(err)
  }

}

// ping every 15 min
setInterval(ping, 1000 * 60 * 15);

console.log('provider created.')

奇怪的是,连接似乎并没有真正断开。我从未在日志中看到任何“供应商错误”或“供应商终止”。

日志看起来像这样,每 15 分钟 ping 一次,但再也听不到任何“GuessSubmitted”事件!! ????

我认为问题可能出在我的 eth 连接提供程序上,但我现在已经尝试使用 Alchemy、Infura 和 GetBlock!这个“停止听到事件”问题发生在所有三个问题上,所以我想知道可能是什么问题,如果它是以太坊平台中的一些潜在错误,或者我在代码中犯了一些错误......

谢谢!

【问题讨论】:

  • 又一次发生在我身上!我认为这是以太坊本身的一个**非常**的关键问题!!!遗憾的是它仍然存在这么多问题并且没有解决方案...... ????
  • 您说“...ping 每 15 分钟一次正常...”,但在您的示例输出中,您只显示“Sending a ping!...”日志消息。没有“Got blocknum:...”日志消息。所以检查很明显,你实际上得到了对你的 ping 请求的响应,对吗?
  • @kaliatech 是的,它每次都显示“pong”日志。

标签: node.js events blockchain solidity ethers.js


【解决方案1】:

如果您查看 web3.js 项目问题,有很多关于断开/关闭/重新连接无法按预期工作的报告:

没有唯一的解决方案,afaict。正在进行重写以解决一些问题:

【讨论】:

  • 我不认为这个问题与“断开/关闭/重新连接”有关,因为我看到了“pong”日志......这是调度solidity事件的侦听器的问题。
猜你喜欢
  • 2011-03-03
  • 2023-03-14
  • 2015-08-18
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
相关资源
最近更新 更多