我试图将一个快速的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#代码之间进行通信?
答案 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;
}
}