从 edge.js 与 C# 主机通信

Communicate with C# host from edge.js

我正在尝试组装一个快速节点。js/edge.js/C# 用于演示的桥接器。

我必须使用 ".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# 应用程序之间来回通信。

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

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

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

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');
            });
          });
        }    
    ");    
}

我最终得到了这样的结果:在传递给 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;
    }
}