2016-04-25 2 views
0

Я пытаюсь собрать быстрый узел node.js/edge.js/C# для демонстрации.Общайтесь с хостом C# из edge.js

Мне нужно использовать стиль ".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: '[email protected]', 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# в цикле событий с помощью обратного вызова?

ответ

0

я закончил с чем-то вроде этого: есть функция, определенная на данных, передаваемых к краю, которое затем вызывает, когда получено новое сообщение. Затем эта функция ожидает ответа и передает его обратно к краю, который получает результат (конечно) другого обратного вызова.

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; 
    } 
} 
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: '[email protected]', 
      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'); 
      }); 
      }); 
     }  
    ");  
} 
+0

Это было очень полезно, спасибо: к сожалению, краю не понравилось, что его вызывали несколько раз (вызов обратного вызова края завершает сеанс edge), поэтому мне пришлось его строить. – stuartd