简体   繁体   English

如何解决#hyperledger-Composer V0.14解组错误

[英]How to resolve #hyperledger-Composer V0.14 unmarshalling error

I have just moved from V0.13.2 to V0.14.2 and am now getting following error in event processing. 我刚刚从V0.13.2迁移到V0.14.2,现在在事件处理中遇到以下错误。 The error appears to be in the composer-client code, not mine. 该错误似乎是在composer-client代码中,而不是我的。 Any ideas on resolving? 有解决的想法吗? Events are still being posted and processed by my app, so my code still appears to work, but the presence of these error messages is troubling and their volume is overwhelming my console window. 事件仍由我的应用发布和处理,因此我的代码仍然可以正常工作,但是这些错误消息的存在令人不安,并且它们的数量使我的控制台窗口不堪重负。

error: [EventHub.js]: on.data - Error unmarshalling transaction= TypeError: Cannot read property 'getSerializer' of null
    at events.forEach (<path>Z2B_Master/Chapter12/node_modules/composer-client/lib/businessnetworkconnection.js:483:73)
    at Array.forEach (native)
    at HLFConnection.connection.on (<path>Z2B_Master/Chapter12/node_modules/composer-client/lib/businessnetworkconnection.js:482:29)
    at emitOne (events.js:96:13)
    at HLFConnection.emit (events.js:188:7)
    at ChainCodeCBE.ccEvent.eventHubs.(anonymous function).registerChaincodeEvent [as onEvent] (<path>Z2B_Master/Chapter12/node_modules/composer-connector-hlfv1/lib/hlfconnection.js:231:22)
    at <path>Z2B_Master/Chapter12/node_modules/fabric-client/lib/EventHub.js:810:12
    at Set.forEach (native)
    at EventHub._processChainCodeOnEvents (<path>Z2B_Master/Chapter12/node_modules/fabric-client/lib/EventHub.js:808:14)
    at ClientDuplexStream.<anonymous> (<path>Z2B_Master/Chapter12/node_modules/fabric-client/lib/EventHub.js:311:10)

This error is not present using identical code in V0.13. 使用V0.13中的相同代码不会出现此错误。

All events are emitted via a single function in the sample.js file. 所有事件都是通过sample.js文件中的单个函数发出的。 A transaction calls the function as in the following example: 事务调用该函数,如以下示例所示:

/**
 * create an order to purchase
 * @param {org.acme.Z2BTestNetwork.CreateOrder} purchase - the order to be processed
 * @transaction
 */
function CreateOrder(purchase) {
    purchase.order.buyer = purchase.buyer;
    purchase.order.amount = purchase.amount;
    purchase.order.financeCo = purchase.financeCo;
    purchase.order.created = new Date().toISOString();
    purchase.order.status = JSON.stringify(orderStatus.Created);
    return getAssetRegistry('org.acme.Z2BTestNetwork.Order')
        .then(function (assetRegistry) {
            return assetRegistry.update(purchase.order)
            .then (function (_res) 
            {
                z2bEmit('Created', purchase.order);
                return (_res);
            }).catch(function(error){return(error);});
        });
}

Each transaction calls the z2bEmit function with a unique _event string. 每个事务都使用唯一的_event字符串调用z2bEmit函数。

function z2bEmit(_event, _order)
{
    var method = 'z2bEmit';
    var factory = getFactory();
    var z2bEvent = factory.newEvent(ns, _event);
    z2bEvent.orderID = _order.$identifier;
    z2bEvent.buyerID = _order.buyer.$identifier;
    emit(z2bEvent);
    return
}

_order is a defined asset in the cto file, _event is a defined event in the cto file. _order_order已定义资产, _event_event文件中的已定义事件。

The client side code has a single routine, executed once, to set up monitoring: 客户端代码具有一个例程,执行一次即可设置监视:

/**
 * Register for all of the available Z2BEvents
 * @param {express.req} req - the inbound request object from the client
 * @param {express.res} res - the outbound response object for communicating back to client
 * @param {express.next} next - an express service to enable post processing prior to responding to the client
*/
exports.init_z2bEvents = function (req, res, next)
{
    var method = 'init_z2bEvents';
    if (bRegistered) {res.send('Already Registered');}
    else{
        bRegistered = true;
        let _conn = svc.createAlertSocket();
        let businessNetworkConnection;
        businessNetworkConnection = new BusinessNetworkConnection();
        // following line added to deal with eventListener error message that more eventListeners needed to be added
        businessNetworkConnection.setMaxListeners(50);
        return businessNetworkConnection.connect(config.composer.connectionProfile, config.composer.network, config.composer.adminID, config.composer.adminPW)
        .then(() => {
            businessNetworkConnection.on('event', (event) => {_monitor(svc.al_connection, svc.f_connection, event); });
            res.send('event registration complete');
        }).catch((error) => {
            console.log(method+' business network connection failed'+error.message); 
            res.send(method+' business network connection failed'+error.message);
        });
    }
}

The connectionProfile is 'hlfv1' connectionProfile为“ hlfv1”

and a single monitor routine, which figures out what kind of event has been posted and then uses a web socket to send that info to a browser so that an alert icon can be posted or updated. 和一个监视器例程,该例程确定已发布的事件类型,然后使用Web套接字将该信息发送到浏览器,以便可以发布或更新警报图标。 A shortened version of that function follows. 该功能的缩写形式如下。 _conn _f_conn continue to work correctly. _conn _f_conn继续正常工作。 The _event information is being passed in and continues to parse correctly. _event信息正在传递并继续正确解析。 The eventhub.js messages appear on every alert, irrespective of how long the program runs. 无论程序运行多长时间,eventhub.js消息都会显示在每个警报上。

/**
 * _monitor
 * @param {web.socket} _conn - web socket connection for general alerts
 * @param {web.socket} _f_conn - web socket for finance alerts
 * @param {org.acme.z2bNetwork.Event} _event - the event just emitted
 * 
 */
function _monitor(_conn, _f_conn, _event)
{
    var method = '_monitor';
    console.log(method+ ' _event received: '+_event.$type+' for Order: '+_event.orderID);
    var event = {};
    event.type = _event.$type;
    event.orderID = _event.orderID;
    event.ID = _event.buyerID;
    _conn.sendUTF(JSON.stringify(event));

    switch (_event.$type)
    {
        case 'Created':
        break;
        case 'Bought':
        case 'PaymentRequested':
            event.ID = _event.sellerID;
            _conn.sendUTF(JSON.stringify(event));
            event.ID = _event.financeCoID;
            _f_conn.sendUTF(JSON.stringify(event));
        break;
        case 'Ordered':
        case 'Cancelled':
        case 'Backordered':
            event.ID = _event.sellerID;
            _conn.sendUTF(JSON.stringify(event));
            event.ID = _event.providerID;
            _conn.sendUTF(JSON.stringify(event));
        break;
        default:
        break;
    }

}

虽然无法确定此问题的根本原因,但随着hyperledger-composer V0.15.2的发布(并升级到)而消失了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM