MetaMask/json-rpc-engine
https://github.com/MetaMask/json-rpc-engine
RpcEngine——MetaMask/json-rpc-engine
https://github.com/MetaMask/json-rpc-engine
a tool for processing JSON RPC
usage
- const RpcEngine = require('json-rpc-engine')
- let engine = new RpcEngine()
Build a stack of json rpc processors by pushing in RpcEngine middleware.
通过push RpcEngine中间件构建一个json rpc处理器堆栈,处理步骤为先进后出,handle时得到的结果是与push时作出的处理相关的
- engine.push(function(req, res, next, end){
- res.result = 42
- end()
- })
⚠️push是能够对之后handle传入的request(即json rpc的值进行处理,(req, res, next, end)中的req就是handle传入的request)的一些状态进行定义或作出一些相关处理,会在handle处理json rpc时对其造成影响。
比如如果在push中设置res.result = req.id,那么就是将json rpc中传进来的(id: 1)的值传出
res:返回的是在push中经过处理后的json rpc的值,如果push中什么都没有做,那么req与res的值是相同的
JSON RPC are handled asynchronously, stepping down the stack until complete.异步处理request,直到返回结果
- let request = { id: 1, jsonrpc: '2.0', method: 'hello' }
- engine.handle(request, function(err, res){
- // do something with res.result,res.result即为push中设置的true
- })
RpcEngine middleware has direct access to the request and response objects. It can let processing continue down the stack with next()
or complete the request with end()
.RpcEngine中间件可以直接访问请求和响应对象。它可以使用next()继续处理堆栈,也可以使用end()完成请求
- engine.push(function(req, res, next, end){
- if (req.skipCache) return next()
- res.result = getResultFromCache(req)
- end()
- })
By passing a 'return handler' to the next
function, you can get a peek at the result before it returns.
通过将“返回处理程序”传递给下一个函数,您可以在结果返回之前看到它
- engine.push(function(req, res, next, end){
- next(function(cb){//就是先压入堆栈中,不进行处理,等到所以push都解决完后再返回处理
- insertIntoCache(res, cb)
- })
- })
RpcEngines can be nested by converting them to middleware asMiddleware(engine)。rpcengine可以通过将它们转换为中间件(中间件)来嵌套
- const asMiddleware = require('json-rpc-engine/lib/asMiddleware')
- let engine = new RpcEngine()
- let subengine = new RpcEngine()
- engine.push(asMiddleware(subengine))
gotchas陷阱
Handle errors via end(err)
, NOT next(err)
.解决error使用的是end(),而不是next()
- /* INCORRECT */
- engine.push(function(req, res, next, end){
- next(new Error())
- })
- /* CORRECT */
- engine.push(function(req, res, next, end){
- end(new Error())
- })
json-rpc-engine/test/basic.spec.js
举例说明:
- /* eslint-env mocha */
- 'use strict'
- const assert = require('assert')
- const RpcEngine = require('../src/index.js')
- describe('basic tests', function () {
- it('basic middleware test', function (done) {
- let engine = new RpcEngine()
- engine.push(function (req, res, next, end) {
- req.method = 'banana'
- res.result = 42
- end()
- })
- let payload = { id: 1, jsonrpc: '2.0', method: 'hello' }
- engine.handle(payload, function (err, res) {
- assert.ifError(err, 'did not error')
- assert(res, 'has res')
- assert.equal(res.result, 42, 'has expected result')
- assert.equal(payload.method, 'hello', 'original request object is not mutated by middleware') //payload.method仍然是'hello',而不会被改成'banana'
- done()
- })
- })
- it('interacting middleware test', function (done) { //两个push交互
- let engine = new RpcEngine()
- engine.push(function (req, res, next, end) {
- req.resultShouldBe = 42
- next()
- })
- engine.push(function (req, res, next, end) {
- res.result = req.resultShouldBe
- end()
- })
- let payload = { id: 1, jsonrpc: '2.0', method: 'hello' }
- engine.handle(payload, function (err, res) {
- assert.ifError(err, 'did not error')
- assert(res, 'has res')
- assert.equal(res.result, 42, 'has expected result')
- done()
- })
- })
- it('erroring middleware test', function (done) {
- let engine = new RpcEngine()
- engine.push(function (req, res, next, end) {
- end(new Error('no bueno'))//定义一个错误
- })
- let payload = { id: 1, jsonrpc: '2.0', method: 'hello' }
- engine.handle(payload, function (err, res) {
- assert(err, 'did error') //测试发现有错,push中定义的
- assert(res, 'does have response')
- assert(res.error, 'does have error on response')
- done()
- })
- })
- it('empty middleware test', function (done) {
- let engine = new RpcEngine()
- let payload = { id: 1, jsonrpc: '2.0', method: 'hello' } //如果没有push ,handle将报错
- engine.handle(payload, function (err, res) {
- assert(err, 'did error')
- done()
- })
- })
- it('handle batch payloads', function (done) {
- let engine = new RpcEngine()
- engine.push(function (req, res, next, end) {
- res.result = req.id
- end()
- })
- let payloadA = { id: 1, jsonrpc: '2.0', method: 'hello' }
- let payloadB = { id: 2, jsonrpc: '2.0', method: 'hello' }
- let payload = [payloadA, payloadB] //可以一下子handle多个push
- engine.handle(payload, function (err, res) {
- assert.ifError(err, 'did not error')
- assert(res, 'has res')
- assert(Array.isArray(res), 'res is array')
- assert.equal(res[0].result, 1, 'has expected result')
- assert.equal(res[1].result, 2, 'has expected result')
- done()
- })
- })
json-rpc-engine/test/asMiddleware.spec.js
- /* eslint-env mocha */
- 'use strict'
- const assert = require('assert')
- const RpcEngine = require('../src/index.js')
- const asMiddleware = require('../src/asMiddleware.js')
- describe('asMiddleware', function () { //嵌套
- it('basic', function (done) {
- let engine = new RpcEngine()
- let subengine = new RpcEngine()
- let originalReq
- subengine.push(function (req, res, next, end) {
- originalReq = req
- res.result = 'saw subengine'
- end()
- })
- engine.push(asMiddleware(subengine))//将两种嵌套,那么engine就能够使用subengine在push时的定义
- let payload = { id: 1, jsonrpc: '2.0', method: 'hello' }
- engine.handle(payload, function (err, res) {
- assert.ifError(err, 'did not error')
- assert(res, 'has res')
- assert.equal(originalReq.id, res.id, 'id matches')
- assert.equal(originalReq.jsonrpc, res.jsonrpc, 'jsonrpc version matches')
- assert.equal(res.result, 'saw subengine', 'response was handled by nested engine')
- done()
- })
- })
- })
json-rpc-engine/src/idRemapMiddleware.js
- const getUniqueId = require('./getUniqueId')
- module.exports = createIdRemapMiddleware
- function createIdRemapMiddleware() {
- return (req, res, next, end) => {
- const originalId = req.id
- const newId = getUniqueId()
- req.id = newId
- res.id = newId
- next((done) => {
- req.id = originalId
- res.id = originalId
- done()
- })
- }
- }
测试:
json-rpc-engine/test/idRemapMiddleware.spec.js
- /* eslint-env mocha */
- 'use strict'
- const assert = require('assert')
- const RpcEngine = require('../src/index.js')
- const createIdRemapMiddleware = require('../src/idRemapMiddleware.js')
- describe('idRemapMiddleware tests', function () {
- it('basic middleware test', function (done) {
- let engine = new RpcEngine()
- const observedIds = {
- before: {},
- after: {},
- }
- engine.push(function (req, res, next, end) {
- observedIds.before.req = req.id
- observedIds.before.res = res.id //设置使得handle时 res.id = req.id,两者结果相同
- next()
- })
- engine.push(createIdRemapMiddleware())
- engine.push(function (req, res, next, end) {
- observedIds.after.req = req.id
- observedIds.after.res = res.id
- // set result so it doesnt error
- res.result = true
- end()
- })
- let payload = { id: 1, jsonrpc: '2.0', method: 'hello' }
- const payloadCopy = Object.assign({}, payload)
- engine.handle(payload, function (err, res) {
- assert.ifError(err, 'did not error')
- assert(res, 'has res')
- // collected data
- assert(observedIds.before.req, 'captured ids')
- assert(observedIds.before.res, 'captured ids')
- assert(observedIds.after.req, 'captured ids')
- assert(observedIds.after.res, 'captured ids')
- // data matches expectations
- assert.equal(observedIds.before.req, observedIds.before.res, 'ids match') //一开始两个是相同的
- assert.equal(observedIds.after.req, observedIds.after.res, 'ids match') //之后两个的结果也是相同的,但是变成了newId
- // correct behavior
- assert.notEqual(observedIds.before.req, observedIds.after.req, 'ids are different') //前后的req.id不同了
- assert.equal(observedIds.before.req, res.id, 'result id matches original') //但是before和最后输出的结果res.id还是一样的
- assert.equal(payload.id, res.id, 'result id matches original')
- assert.equal(payloadCopy.id, res.id, 'result id matches original')
- done()
- })
- })
- })
这里可以知道idRemapMiddleware的作用是在过程中间得到一个新的、比较复杂的Id进行一系列处理,但是最后输出的给用户看的表示结果还是一样的
MetaMask/json-rpc-engine的更多相关文章
- 測试JSON RPC远程调用(JSONclient)
#include <string> #include <iostream> #include <curl/curl.h> /* 标题:JSonclient Auth ...
- metamask源码学习-metamask-controller.js
The MetaMask Controller——The central metamask controller. Aggregates other controllers and exports a ...
- Guide to Porting MetaMask to a New Environment
https://github.com/MetaMask/metamask-extension/blob/develop/docs/porting_to_new_environment.md MetaM ...
- MetaMask/json-rpc-middleware-stream
https://github.com/MetaMask/json-rpc-middleware-stream/blob/master/test/index.js#L20 A small toolset ...
- MetaMask/metamask-inpage-provider
https://github.com/MetaMask/metamask-inpage-provider Used to initialize the inpage ethereum provider ...
- mascara-2(MetaMask/mascara本地实现)-连接线上钱包
https://github.com/MetaMask/mascara (beta) Add MetaMask to your dapp even if the user doesn't have t ...
- metamask源码学习-inpage.js
The most confusing part about porting MetaMask to a new platform is the way we provide the Web3 API ...
- MetaMask/provider-engine-1
https://github.com/MetaMask/provider-engine 在学习这个之前应该先看一下什么是zero-client,MetaMask/zero-client Web3 Pr ...
- metamask源码学习-contentscript.js
When a new site is visited, the WebExtension creates a new ContentScript in that page's context, whi ...
随机推荐
- Java并发编程-闭锁
闭锁是一种同步器 ( Synchronizer ),它可以延迟线程的进度直到线程到达终止状态,CountDownLatch是一个灵活的闭锁实现:1)允许一个或多个线程等待一个事件集的发生,闭锁的状态包 ...
- 自己写一个java的mvc框架吧(三)
自己写一个mvc框架吧(三) 根据Method获取参数并转换参数类型 上一篇我们将url与Method的映射创建完毕,并成功的将映射关系创建起来了.这一篇我们将根据Method的入参参数名称.参数类型 ...
- 【Dubbo&&Zookeeper】1、Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
转自:http://blog.csdn.net/congcong68/article/details/41113239 互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架 ...
- 【Linux】安装openssh-server依赖openssh-client版本错误的解决办法
这是因为,openssh-server是依赖于openssh-clien的,ubuntu自带了openssh-client,自带的openssh-clien与所要安装的openssh-server所依 ...
- 深入理解Java虚拟机--阅读笔记二
垃圾收集器与内存分配策略 一.判断对象是否已死 1.垃圾收集器在对堆进行回收前,要先判断对象是否已死.而判断的算法有引用计数算法和可达性分析算法: 2.引用计数算法是给对象添加引用计数器,有地方引用就 ...
- 【13】享元模式(FlyWeight Pattern)
一.引言 在软件开发过程,如果我们需要重复使用某个对象的时候,若重复地使用new创建这个对象的话,就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非常严重.享元模式可以 ...
- DNS协议详解
DNS协议详解 简介 DNS(Domain Name System)域名系统,主要实现的功能是将域名转换成ip地址的一个服务.它是由一个分层的DNS服务器实现的分布式数据库,同时.他也是一个使得主机能 ...
- url override and HttpSession implements session for form
url 重写结合HttpSession实现会话管理之 form 提交 package com.test; import javax.servlet.ServletException; import j ...
- Oracle EBS INV创建保留
CREATE or REPPLACE PROCEDURE CreateReservation AS -- Common Declarations l_api_version NUMBER := 1.0 ...
- MySQL-死锁查询
1.查询是否锁表 show OPEN TABLES where In_use > 0; 查询到相对应的进程 === 然后 kill id 2.查询进程 show processlist 补 ...