Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript web3 websocket连接阻止节点进程退出_Javascript_Websocket_Ethereum_Solidity_Web3 - Fatal编程技术网

Javascript web3 websocket连接阻止节点进程退出

Javascript web3 websocket连接阻止节点进程退出,javascript,websocket,ethereum,solidity,web3,Javascript,Websocket,Ethereum,Solidity,Web3,我有一个创建web3 websocket连接的node js进程,如下所示: web3 = new Web3('ws://localhost:7545') 当进程完成时(我向它发送一个SIGTERM),它不会退出,而是永远挂起,没有控制台输出 我在SIGINT和SIGTERM上注册了一个监听器,以观察进程在进程中有哪些未完成的句柄。\u getActiveRequests()和进程。\u getActiveHandles(),我看到了以下内容: Socket { connecting

我有一个创建web3 websocket连接的node js进程,如下所示:

web3 = new Web3('ws://localhost:7545')
当进程完成时(我向它发送一个SIGTERM),它不会退出,而是永远挂起,没有控制台输出

我在SIGINT和SIGTERM上注册了一个监听器,以观察进程在
进程中有哪些未完成的句柄。\u getActiveRequests()
进程。\u getActiveHandles()
,我看到了以下内容:

 Socket {
    connecting: false,
    _hadError: false,
    _handle: 
     TCP {
       reading: true,
       owner: [Circular],
       onread: [Function: onread],
       onconnection: null,
       writeQueueSize: 0 },
    <snip>
    _peername: { address: '127.0.0.1', family: 'IPv4', port: 7545 },
    <snip>
}
看起来web3打开了一个套接字,这很有意义,因为我从未告诉它关闭连接。通过查看文档和谷歌搜索,web3对象似乎没有关闭或结束方法

在上面的
stop
中手动关闭套接字可使进程成功退出:

web3.currentProvider.connection.close()

有人有更优雅或官方认可的解决方案吗?我觉得很有趣,您必须手动执行此操作,而不是让对象在进程结束时自行销毁。其他客户端似乎会自动执行此操作,而不会明确告诉他们关闭连接。也许告诉您的节点进程创建的所有客户端在关机时关闭它们的句柄/连接会更干净,但对我来说,这是出乎意料的。

在您的节点进程结束时,只需调用:

web3.currentProvider.connection.close()
我觉得很有趣的是,您必须手动执行此操作,而不是让对象在进程结束时自行销毁

这感觉很有趣,因为与异步编程相比,您可能接触到了更多的同步编程。考虑下面的代码

fs = require('fs')
data = fs.readFileSync('file.txt', 'utf-8');
console.log("Read data", data)
当您在上面运行时,您将获得输出

$ node sync.js
Read data Hello World
这是一个同步代码。现在考虑相同版本

的异步版本
fs = require('fs')
data = fs.readFile('file.txt', 'utf-8', function(err, data) {
    console.log("Got data back from file", data)
});
console.log("Read data", data);
当您运行时,您将获得以下输出

$ node async.js
Read data undefined
Got data back from file Hello World
现在,如果您认为作为一个同步程序员,程序应该在最后一个
console.log(“读取数据”,data)处结束,但您得到的是随后打印的另一条语句。这感觉好笑吗?让我们向流程中添加一个exit语句

fs = require('fs')
data = fs.readFile('file.txt', 'utf-8', function(err, data) {
    console.log("Got data back from file", data)
});
console.log("Read data", data);
process.exit(0)
现在,当您运行程序时,它将在最后一条语句结束

$ node async.js
Read data undefined
但该文件实际上并没有被读取。为什么?因为您从未给JavaScript引擎时间来执行挂起的回调。理想情况下,当一个进程没有剩余的工作(没有挂起的回调、函数调用等)时,它会自动完成。这就是异步世界的工作方式。有一些好的线索和文章,你应该看看


因此,在异步世界中,您需要告诉进程退出,或者在没有挂起的任务时它将自动退出(您知道如何检查-
process.\u getActiveRequests()
process.\u getActiveHandles()

由于和的实现,JavaScript web3模块的提供程序API最近经历了一些重大变化

根据,它看起来像是
web3.currentProvider.disconnect()
应该可以工作。此方法还接受可选的
code
reason
参数,如中所述

重要提示:您会注意到我引用了上面的源代码,而不是文档。这是因为目前,
disconnect
方法不被认为是公共API的一部分。如果您在代码中使用它,您应该确保为它添加一个测试用例,因为它可能随时中断
据我所见,
WebSocketProvider.disconnect
是在
web3@1.0.0-beta.38
至今仍存在于最新版本中,即
web3@1.0.0-beta.55
。考虑到稳定的1.0.0版本即将推出,我认为从现在到
web3@1.0.0
,但在内部API的结构方面没有任何限制

我已经与当前的维护人员Samuel Furter(又名GitHub上的nividia)详细讨论了如何公开内部提供者。我不完全同意他将其保留在内部的决定,但为他辩护,他是目前唯一的维护者,他一直忙于稳定
1.0
分支上正在进行的长期工作

通过这些讨论,我目前的观点是,那些需要为WebSocket提供商提供稳定API的人应该自己编写一个与EIP-1193兼容的提供商,并将其发布在NPM上供其他人使用。为此,请遵循semver,并在您自己的公共API中包含类似的
disconnect
方法。如果使用
TypeScript
编写,则会获得额外的积分,因为这样可以将类成员显式声明为
public
protected
private


如果您这样做,请注意EIP-1193仍处于草稿状态,因此您需要密切关注中的EIP-1193讨论,以了解可能发生的任何更改。

当流程完成时,您所说的
是什么意思?您的进程是一个侦听端口的HTTP服务器。它怎么知道应该停止监听?对不起,我不清楚这个过程是如何完成的。我正在向节点进程发送终止信号。express和mongo似乎在进程退出时自动关闭句柄,但web3没有。它在哪个系统上运行?你的流程有子流程吗?debian jessie。没有一个孩子在Docker容器内运行,尽管我认为这不重要。我想我不清楚自己的期望。我更新了这个问题,希望它更容易理解。我觉得有趣的不是事件循环是如何工作的,而是web3客户端没有监听进程退出和清理的事实。@AndyPang,这件事,你的期望是一个陷阱22。只有在没有挂起的内容时,您的进程才会退出。
websocket
是一个连续的开放通道,假定它保持开放。在NodeJS中,事情不会自行关闭
$ node async.js
Read data undefined