Geth v1.4和更高版本支持使用JSON-RPC通知进行发布/订阅。这使客户端可以等待事件,而不是轮询事件。
它通过订阅特定事件来工作。该节点将返回订阅ID。对于与订阅匹配的每个事件,带有相关数据的通知将与订阅ID一起发送。
例子:
// create subscription
>> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {}]}
<< {"jsonrpc":"2.0","id":1,"result":"0xcd0c3e8af590364c09d0fa6a1210faf5"}
// incoming notifications
<< {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0xcd0c3e8af590364c09d0fa6a1210faf5","result":{"difficulty":"0xd9263f42a87",<...>, "uncles":[]}}}
<< {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0xcd0c3e8af590364c09d0fa6a1210faf5","result":{"difficulty":"0xd90b1a7ad02", <...>, "uncles":["0x80aacd1ea4c9da32efd8c2cc9ab38f8f70578fcd46a1a4ed73f82f3e0957f936"]}}}
// cancel subscription
>> {"id": 1, "method": "eth_unsubscribe", "params": ["0xcd0c3e8af590364c09d0fa6a1210faf5"]}
<< {"jsonrpc":"2.0","id":1,"result":true}
注意事项
- 通知是针对当前事件而不是针对过去事件发送的。如果您的用例要求您不要错过任何通知,那么订阅可能不是最佳选择。
- 订阅需要全双工连接。Geth以WebSocket和IPC的形式提供此类连接(默认情况下启用)。
- 订阅耦合到连接。如果连接已关闭,则将删除通过此连接创建的所有订阅。
- 通知存储在内部缓冲区中,并从该缓冲区发送到客户端。如果客户端无法跟上,并且缓冲的通知数达到限制(当前为10k),则连接将关闭。请记住,订阅某些事件可能会导致大量通知,例如,在节点开始同步时侦听所有日志/块。
创建订阅
订阅是通过常规RPC调用创建的,其中RPCeth_subscribe
作为方法,订阅名称为第一个参数。如果成功,则返回订阅ID。
参数
- 订阅名称
- 可选参数
例子
>> {"id": 1, "method": "eth_subscribe", "params": ["newHeads", {"includeTransactions": true}]}
<< {"id": 1, "jsonrpc": "2.0", "result": "0x9cef478923ff08bf67fde6c64013158d"}
取消订阅
使用常规的RPC调用(eth_unsubscribe
作为方法,订阅ID作为第一个参数)取消订阅。它返回一个布尔值,指示是否成功取消了订阅。
参数
- 订阅编号
例子
>> {"id": 1, "method": "eth_unsubscribe", "params": ["0x9cef478923ff08bf67fde6c64013158d"]}
<< {"jsonrpc":"2.0","id":1,"result":true}
支持的订阅
newHeads
每次将新标头附加到链(包括链重组)时,都会触发通知。用户可以使用Bloom筛选器来确定该块是否包含对其感兴趣的日志。
如果发生链重组,则订阅将发出新链的所有新标头。因此,订阅可以在相同高度上发出多个标头。
例子
>> {"id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
<< {"jsonrpc":"2.0","id":2,"result":"0x9ce59a13059e417087c02d3236a0b1cc"}
<< {
"jsonrpc": "2.0",
"method": "eth_subscription",
"params": {
"result": {
"difficulty": "0x15d9223a23aa",
"extraData": "0xd983010305844765746887676f312e342e328777696e646f7773",
"gasLimit": "0x47e7c4",
"gasUsed": "0x38658",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
"nonce": "0x084149998194cc5f",
"number": "0x1348c9",
"parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701",
"receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378",
"timestamp": "0x56ffeff8",
"transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f"
},
"subscription": "0x9ce59a13059e417087c02d3236a0b1cc"
}
}
日志
返回包含在新导入的块中并符合给定过滤条件的日志。
如果进行链重组,则将重新发送旧链上的先前发送的日志,并将removed
属性设置为true。发出来自结束于新链中的事务的日志。因此,订阅可以多次发出同一事务的日志。
参数
-
object
具有以下(可选)字段- address,一个地址或一个地址数组。仅返回从这些地址创建的日志(可选)
- topic,仅匹配指定主题的日志(可选)
例子
>> {"id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}
<< {"jsonrpc":"2.0","id":2,"result":"0x4a8a4c0517381924f9838102c5a4dcb7"}
<< {"jsonrpc":"2.0","method":"eth_subscription","params": {"subscription":"0x4a8a4c0517381924f9838102c5a4dcb7","result":{"address":"0x8320fe7702b96808f7bbc0d4a888ed1468216cfd","blockHash":"0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04","blockNumber":"0x29e87","data":"0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003","logIndex":"0x0","topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],"transactionHash":"0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4","transactionIndex":"0x0"}}}
newPendingTransactions
返回添加到挂起状态并使用节点中可用密钥签名的所有事务的哈希。
如果重新定义后,以前属于规范链的交易不属于新规范链,则再次发出该交易。
参数
没有
例子
>> {"id": 1, "method": "eth_subscribe", "params": ["newPendingTransactions"]}
<< {"jsonrpc":"2.0","id":2,"result":"0xc3b33aa549fb9a60e95d21862596617c"}
<< {
"jsonrpc":"2.0",
"method":"eth_subscription",
"params":{
"subscription":"0xc3b33aa549fb9a60e95d21862596617c",
"result":"0xd6fdc5cc41a9959e922f30cb772a9aef46f4daea279307bc5f7024edc4ccd7fa"
}
}
正在同步
指示节点何时开始或停止同步。结果可以是指示同步已开始(true),完成(false)的布尔值,也可以是具有各种进度指示器的对象。
参数
没有
例子
>> {"id": 1, "method": "eth_subscribe", "params": ["syncing"]}
<< {"jsonrpc":"2.0","id":2,"result":"0xe2ffeb2703bcf602d42922385829ce96"}
<< {"subscription":"0xe2ffeb2703bcf602d42922385829ce96","result":{"syncing":true,"status":{"startingBlock":674427,"currentBlock":67400,"highestBlock":674432,"pulledStates":0,"knownStates":0}}}}