【发布时间】: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