zoukankan      html  css  js  c++  java
  • MetaMask/json-rpc-engine

    https://github.com/MetaMask/json-rpc-engine

    RpcEngine——/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进行一系列处理,但是最后输出的给用户看的表示结果还是一样的

     
  • 相关阅读:
    如何高效的利用博客园?
    [Asp.net]常见数据导入Excel,Excel数据导入数据库解决方案,总有一款适合你!
    [c#基础]关于const和readonly常见的笔试题剖析
    [Asp.net]常见word,excel,ppt,pdf在线预览方案,有图有真相,总有一款适合你!
    [c#基础]关于try...catch最常见的笔试题
    [UML]UML系列——时序图(顺序图)sequence diagram
    [转]winscp以命令行方式同步服务器数据到PC机磁盘上
    Mysql配置参数说明
    安装最新Nginx
    [CentOS7]redis设置开机启动,设置密码
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/9884219.html
Copyright © 2011-2022 走看看