与edge.js

时间:2016-04-25 17:02:12

标签: javascript c# node.js edge.js

我试图将一个快速的node.js / edge.js / C#bridge放在一起进行演示。

我必须使用".Net calling Node.js"样式,因为现有的C#代码使用了许多配置值,我无法添加到node.exe.config,因为我需要同时运行多个版本

所以我有这段代码:

private static async Task Start() {

    Func<object, Task<object>> edge = EdgeJs.Edge.Func(@"

        var login = require('login.js');
        var edge = require('edge')

        login({ email: 'user@example.com', password: 'shh' }, function callback(err, api) {

            if (err) return console.error(err);

            // This will keep listening until terminated
            api.listen(function callback(err, message) {
                if (err) return console.error(err);

                // At this point I need to send the message back to this class so it can be processed..
                console.log(message); // send the message to C#

                // ... and then return the response via the api
                api.send('response goes here');      
            });
        });

        return function (data, callback) {
            callback(null, er...);
        }               
    ");    

}

因此,代码正在等待事件循环中的消息并进行响应。这一切都适用于硬编码值。但是我需要将消息提交回C#进行处理,我无法弄清楚如何在edge.js和C#app之间来回通信。

肯定是通过回调,但我似乎无法开始弄清楚如何构建它,时间越来越短。我绝不是JavaScript专家。

如何使用回调在事件循环中的边缘代码和C#代码之间进行通信?

2 个答案:

答案 0 :(得分:1)

你是对的,这是通过回调。由于您使用的是异步代码,因此必须将所有代码包装在返回的(边缘)函数中,如下所示:

private static async Task Start() {
    Func<object, Task<object>> edge = EdgeJs.Edge.Func(@"
        // edge_callback is used to return values to the C# code
        return function(data, edge_callback) {
          var login = require('login.js');
          var edge = require('edge')

          login({
            email: 'user@example.com',
            password: 'shh'
          }, function callback(err, api) {

            if (err) return console.error(err);
            // possible enhancement here by letting C# know there is an error
            // edge_callback(err);

            // This will keep listening until terminated
            api.listen(function callback(err, message) {
              if (err) return console.error(err);
              // same thing here: edge_callback(err);

              // At this point I need to send the message back to this class so it can be processed..
              console.log(message); // send the message to C#
              // use the callback, first param is error if there is any, second is the data
              edge_callback(null, message);

              // ... and then return the response via the api
              api.send('response goes here');
            });
          });
        }    
    ");    
}

答案 1 :(得分:0)

我最终得到了这样的结果:在传递给edge的数据上定义了一个函数,然后在收到新消息时调用该函数。然后该函数等待响应,并将其传递回edge,然后在(当然)另一个回调中接收结果。

private static async Task Start() {
    dynamic payload = new ExpandoObject();
    payload.msgHook = NewMessage;
    payload.login = new {
        email,
        password
    };

    var receive = Edge.Func(@"    

            return function(payload, edge_callback) {

                var login = require('index.js');

                login({
                    email: payload.login.email,
                    password: payload.login.password
                }, function callback(err, api) {

                    if (err) {
                        edge_callback(err); 
                    }

                    api.listen(function callback(err, message) {
                        if (err) { edge_callback(err); }

                        payload.msgHook(message,
                            function callback(err, result) {
                                if (err) {
                                    edge_callback(err);
                                }


                                var msg = {
                                        body: result.body,
                                        url: result.url
                                    }

                                api.sendMessage(msg, result.threadId);
                            });                   
                        });
                    });
                }    
        ");

    var _ = await receive(payload) as IDictionary<string, object>;
}

private static Func<object, Task<object>> NewMessage {
    get {
        Func<object, Task<object>> hook = async m => {
                string body, threadId;

                if (!ProcessMessage(m as IDictionary<string, object>, out body, out threadId)) {
                    log.Error("Failed to process message: " + m.ToString());
                }

                api.SendMessage(body, threadId, phone);
                var reply = await waitForReply(threadId);

            var result = new {
                body = reply
            };

            // Return the _result_ of the task.
            return Task.FromResult<object>(result).Result;
        };

        return hook;
    }
}