如何在节点应用程序中监听两个{websocket + zmq broker}?

时间:2018-02-13 20:16:44

标签: javascript node.js websocket zeromq

我有一个简单的node.js服务器,它使用websocket从交换机获取市场数据,并使用ZeroMQ路由器套接字从GUI前端接收命令。

我有点迷失在如何让这两个人与另一个人玩得很好而没有一个阻止另一个。

这是我尝试过的一件事:

var main = function() {
    console.log(Date().toString());
    try {
        var broker = zmq.socket('router');
        broker.bindSync('tcp://*:5672');

        client.on('connect', function(connection: any) {
            console.log('Connected to Server...');

            connection.on('message', function(message: any) {
                if(message.type === 'utf8') {
                    var obj = JSON.parse(message.utf8Data);
                    console.log(obj);
                    publisher.send(message.utf8Data);
                }
            });

            function send(message: any) {
                if (connection.connected) {
                    connection.sendUTF(message);
                }
            }

            //const quoteTokenInfo = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync("WETH");
            //const baseTokenInfo = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync("ZRX");

            send(`{
            "type": "subscribe",
            "channel": "orderbook",
            "requestId": 1,
            "payload": {
                "baseTokenAddress": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
                "quoteTokenAddress": "0xe41d2489571d322189246dafa5ebde1f4699f498",
                "snapshot": true,
                "limit": 4
            }
            }`);
        });

        client.on('message', function(message: any) {
            var obj = JSON.parse(message.utf8Data);
            console.log(obj);
        });

        client.onmessage = function(message: any) {
            var obj = JSON.parse(message.utf8Data);
            console.log(obj);
        };

        broker.on('message', function () {
            var args = Array.apply(null, arguments);
            var identity = args[0]

            if (args.length < 2) {
                broker.send([identity, 'ERROR']);
                    return;
            }
            var message = args[1].toString('utf8');
            if(args.length > 3) {
                var quote = args[2].toString('utf8');
                var base = args[3].toString('utf8');
            }

            if(message === 'TopOfBook') {
                getTopOfBook(quote, base).then((result) => {
                    broker.send([identity, 'TopOfBook', result])
                }, (err) => {
                    broker.send([identity, 'ERROR']
                )}).catch((error) => {
                    console.log(error);
                });
            } else if(message === 'NewBid') {
                var size = args[4].toString('utf8');
                var rate = args[5].toString('utf8');
                rate = parseFloat(rate);
                rate.toFixed(8);
                placeBid(quote, base, size, rate).then((result) => {
                    broker.send([identity, 'SUCCESS'])
                }, (err) => {
                    broker.send([identity, 'FAILURE']
                )}).catch((error) => {
                    console.log(error);
                });
            } else if(message === 'NewOffer') {
                var size = args[4].toString('utf8');
                var rate = args[5].toString('utf8');
                rate = parseFloat(rate);
                rate.toFixed(8);
                placeOffer(quote, base, size, rate).then((result) => {
                    broker.send([identity, 'SUCCESS'])
                }, (err) => {
                    broker.send([identity, 'FAILURE']
                )}).catch((error) => {
                    console.log(error);
                });
            }
        })
    } catch (err) {
        console.log(err);
    }
}

我还尝试在client.on( 'connect', ... )之外使用 main(){...} 功能。除了初始连接之外,上面的代码不会打印来自websocket的任何消息。如果我在main(){...}之外,它将打印第一个快照并且不打印其他快照。

我也很模糊javascript如何根据代码的组织方式处理消息。例如,在其中有 main(){...} 处理程序的broker.on()函数是否可以,而在外部有 client.on() 处理程序那个main()函数?或者会阻止另一个吗?

关于使用客户端websocket,有什么区别 connection.on( 'message', ... )
vs有 client.onmessage( ... )

任何明确表示赞赏。

1 个答案:

答案 0 :(得分:0)

简短版本:

设计师的责任是始终避免任何类型的阻止,在共享的,共同的事件循环系统下更多。

移动main()范围之外的东西:

这是我宁愿留给javascript福音传播者的一点,核心问题在于正确理解阻塞和事件循环以及处理程序的概念。

ZeroMQ部分:

ZeroMQ是一个很好的工具,但如果更多地考虑到设计最佳实践的系统视图,那么人们将受益最多,而不仅仅是#34;只需复制&#34;一些SLOC-s。分布式系统将一个系统输入一个新的领域,其中一个纯粹的&#34; - [SERIAL]代码执行不起作用。有一本来自Pieter HINTJENS的好书,我建议所有人,他们决定进入设计领域阅读,绝对值得花时间和精力。

因此,使用 .bind() 代替 .bindSync() 似乎是首先要审核的内容。

接下来,在添加另一个事件循环组件之前,始终测试一个事件循环组件,以便找出问题的根本原因。在一个常见的事件循环中组装了一个事件处理程序的毛球将有效地阻止您调试尚未经过测试的组件,并且在代码破坏的情况下,事情可能会在沉默中死亡,而无需知道何处和原因。如果具有同时追踪公共系统资源的多层事件循环,那么这是真的三倍。

要求其他人修复缺乏适当的系统分析工作以及缺乏适当的设计护理是可能的,但这不是一个公平的可行性专业实践。

无论如何,一旦正确使用并愉快交易,享受ZeroMQ的力量。

var main = function() {
 /*.log()--------------------------------------------------------*/ console.log( Date().toString() );
    try {
        var broker = zmq.socket( 'router' );
            broker.bindSync( 'tcp://*:5672' );
         // broker.bind(     'tcp://*:5672' ); // ------------------ NEVER BLOCK 

        client.on( 'connect',
                    function( connection: any ) {
                           /*.log()------------------------------*/ console.log( 'Connected to Server...' );
                              connection.on( 'message',
                                              function( message: any ) {
                                                        if (  message.type === 'utf8' ) {
                                                            var obj = JSON.parse( message.utf8Data );
                                                         /*.log()*/ console.log( obj );
                                                            publisher.send( message.utf8Data );
                                                        }
                                              }
                              );
                            // ------------------------------------------------
                              function send( message: any ) {
                                             if ( connection.connected ) {
                                                  connection.sendUTF( message );
                                             }
                              }

                           // const quoteTokenInfo = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync( "WETH" );
                           // const baseTokenInfo  = await zeroEx.tokenRegistry.getTokenBySymbolIfExistsAsync( "ZRX" );

                              send( `{ "type":      "subscribe",
                                       "channel":   "orderbook",
                                       "requestId":  1,
                                       "payload": { "baseTokenAddress":  "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
                                                    "quoteTokenAddress": "0xe41d2489571d322189246dafa5ebde1f4699f498",
                                                    "snapshot":           true,
                                                    "limit":              4
                                        }
                                       }`
                                   );
                    }
        );            
        client.on( 'message',
                    function( message: any ) {
                              var obj = JSON.parse( message.utf8Data );
                           /*.log()------------------------------*/ console.log( obj );
                    }
        );
        client.onmessage = function( message: any ) {
                                     var obj = JSON.parse( message.utf8Data );
                                  /*.log()-----------------------*/ console.log( obj );
                           };

        broker.on( 'message',
                    function () {
                              var args     = Array.apply( null, arguments );
                              var identity = args[0]

                              if (  args.length <  2 ) {
                                    broker.send( [ identity,
                                                  'ERROR'
                                                   ]
                                                 );
                                    return; // ------------------------------------------^ JIT/RET
                              }
                              var message = args[1].toString( 'utf8' );
                              if (  args.length >  3 ) {
                                    var quote = args[2].toString( 'utf8' );
                                    var base  = args[3].toString( 'utf8' );
                              }

                              if (         message === 'TopOfBook' ) {
                                    getTopOfBook( quote, base ).then( ( result ) => {
                                        broker.send( [ identity,
                                                      'TopOfBook',
                                                       result
                                                       ]
                                                     )
                                    }, ( err ) => {
                                        broker.send( [ identity,
                                                      'ERROR'
                                                       ]
                                                     )
                                    } ).catch( ( error ) => {
                                     /*.LOG:---------------------*/ console.log( error );
                                    } );
                              } else if (  message === 'NewBid' ) {
                                    var size = args[4].toString( 'utf8' );
                                    var rate = args[5].toString( 'utf8' );
                                        rate = parseFloat( rate );
                                        rate.toFixed( 8 );
                                    placeBid( quote, base, size, rate ).then( ( result ) => {
                                        broker.send( [ identity,
                                                      'SUCCESS'
                                                       ]
                                                     )
                                    }, ( err ) => {
                                        broker.send( [ identity,
                                                      'FAILURE'
                                                       ]
                                                     )
                                    } ).catch( ( error ) => {
                                     /*.LOG:---------------------*/ console.log( error );
                                    } );
                              } else if (  message === 'NewOffer' ) {
                                   var size = args[4].toString( 'utf8' );
                                   var rate = args[5].toString( 'utf8' );
                                       rate = parseFloat( rate );
                                       rate.toFixed( 8 );
                                   placeOffer( quote, base, size, rate ).then( ( result ) => {
                                       broker.send( [ identity,
                                                     'SUCCESS'
                                                      ]
                                                    )
                                   }, ( err ) => {
                                       broker.send( [ identity,
                                                     'FAILURE'
                                                      ]
                                                    )
                                   } ).catch( ( error ) => {
                                    /*.LOG:----------------------*/ console.log( error );
                                   } );
                              }
                    }
        )
    }
    catch ( err ) {
     /*.LOG:-----------------------------------------------------*/ console.log( err );
    }
}