使用expess监听web3事件之二(完结篇):使用WEB3 监听合约事件,并在服务内使用mitt事件总线进行事件分发

在上一章使用expess监听web3事件之一:环境搭建_lixiaodog的博客-CSDN博客中我们搭建好了EXPRESS的开发框架,在本章我们将在这个框架下调用WEB3模块监听目标合约。实际上如果单纯为监听合约,并不需要EXPRESS,但是一个真正的DAPP会有相当数量数据会存储到本地,而并不是使用的时候才去链上查找 ,那样太慢了,正常是做法是把链上数据同步到本地的数据库,客户使用时,直接查询本地数据。而为客户提供这个查询能力一般是通过提供一组供客户调用的API来实现的。这个时候EXPRESS就会提供大量的方便的模块供我们使用, 为了方便演示所以采用了EXPRESS。

在根目录下创建一个文件夹,并创建3个文件,目录结构如下:

 代码如下:

contracts.js

const config ={
    GameManage:require("../../build/contracts/GameManage.json"),
    GameManageProxy:require("../../build/contracts/GameManageProxy.json"),
    TutorialToken:require("../../build/contracts/TutorialToken.json"),
    BaseDesk:require("../../build/contracts/BaseDesk.json"),
}
module.exports = config;

eventbus.js

var mitt = require("mitt");
const emitter = mitt();
module.exports = emitter;

watcher.js

var Web3 = require('Web3')
var config = require('./contracts.js')
var contract = require('@truffle/contract')
var emitter = require('./eventbus.js')

const watcher = {
  contracts: {},
  instances: {},
  eventManager: {},
  roomList: {},
  roomInfo: {},
  deskInfo: {},
  player: {},
  start: function (options) {
    console.log('watcher start')

    this.web3Provider = new Web3.providers.WebsocketProvider('http://127.0.0.1:8545')

    this.eventManager = emitter

    web3 = new Web3(this.web3Provider)
    this.web3 = web3

    this.initContract()
  },
  initContract: async function () {
    this.contracts.GameManageProxy = contract(config.GameManageProxy)

    this.contracts.GameManageProxy.setProvider(this.web3Provider)

    this.contracts.GameManage = contract(config.GameManage)
    this.contracts.GameManage.setProvider(this.web3Provider)
    this.contracts.GameManageProxy.deployed()
      .then((instance) => this.contracts.GameManage.at(instance.address))
      .then((instance) => {
        this.instances.GameManage = instance;
        console.log("watcher start");
        this.startWatch();
        
      })
      

    this.contracts.TutorialToken = contract(config.TutorialToken)
    this.contracts.TutorialToken.setProvider(this.web3Provider)
    await this.contracts.TutorialToken.deployed().then(
      (instance) => (this.instances.TutorialToken = instance),
    )

    this.contracts.BaseDesk = contract(config.BaseDesk)
    this.contracts.BaseDesk.setProvider(this.web3Provider)
  },

  startWatch: async function () {
      let self = this;
    //开始监听所有事件
    this.watchTarget = new this.web3.eth.Contract(
      config.GameManage.abi,
      this.instances.GameManage.address,
    )

    this.allEvent = this.watchTarget.events.allEvents(function (
      error,
      result,
    ) {
      if (error) {
        console.log('event error', error)
      } else {
        //此处响应所有事件
        self.eventManager.emit(result.event, result.returnValues);
         console.log("event", result);
      }
    })
  },
}
module.exports = watcher

 这里可以替换任何自己想要监听的合约。

在响应事件的地方,一般是添加数据库写入操作等等。

在APP.JS里加入代码:

watcher.start();
app.watcher = watcher;

此时打开我们的在上一系列中的ROOMLIST页面:

         addRoom的响应函数如下:

    //添加桌子
    addDesk(row, index) {

      let deskInfo = DataDef.DeskInfo();
      
      deskInfo.name = 0;
      deskInfo.addr = this.$store.state.userInfo.data.userData.username;
      deskInfo.creator = this.$store.state.userInfo.data.userData.username;
      deskInfo.owner = this.$store.state.userInfo.data.userData.username;
      deskInfo.password = "";
      deskInfo.token = myWeb3.instances.TutorialToken.address;
      deskInfo.bonus = 0;
      deskInfo.state = 0;
  
     
        myWeb3.instances.GameManage.createDesk(row.name, deskInfo,{from:this.$store.state.userInfo.data.userData.username, value: myWeb3.web3.utils.toWei('10')})
       .then(res => {
        console.log(userCharge);
      })
    },

执行后,我们的后台会收到event: 'DeskCreated'

 到此,我们的事件接收服务已经编写完成,接收到事件可以做保存数据的操作。本文中为了方便,把服务建立 在EXPRESS中,实际上应该和API服务剥离,这样某一服务出了问题,不至于影响链上数据的保存。

猜你喜欢

转载自blog.csdn.net/lixiaodog/article/details/124713101