C#とNode.jsを連携する
EdgeJSはNode.jsから呼ぶとC#のソースを文字列にしそれをコンパイルしています。ソースだろうとファイルだろうとDllだろうとC#を一旦文字列化し、再度ビルドします。
Nugetを読んでたり、外部DLLを参照していたり、Puhblishで書き出したものをすべて読み込んだりすると、Dllが足りなかったり、edgeJSを上書きしバージョンが違ってしまったりで、いろいろうまく動作しないことが多いです。
プログラムが複雑になると開発が難しくなる懸念があります。
そこでC#のコンソールアプリを別個に作り、外部プロセスでコンソールアプリを実行し結果Jsonなどで標準出力し、それをNode.js側に戻すのが開発効率がよいと考えました。
サンプルファイル
一式をGitに上げました
Node.jsからコンパイルされるC#文
コンソールアプリを実行するだけのシンプルなものになりました。
public class Startup
{
public async Task<object> Invoke(object input)
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
// 子プロセスの実行ファイル名
p.StartInfo.FileName = "ConsoleApp1/bin/Debug/net5.0/ConsoleApp1";
// 子プロセスのオプション(もしあれば)
p.StartInfo.Arguments = "-n";
// コンソール・ウィンドウを開かない
p.StartInfo.CreateNoWindow = true;
// シェル機能を使用しない
p.StartInfo.UseShellExecute = false;
// 標準出力をリダイレクト
p.StartInfo.RedirectStandardOutput = true;
// 標準入力をリダイレクト
p.StartInfo.RedirectStandardInput = true;
p.Start(); // 子プロセスの実行開始
// 子プロセスの出力の読み込み
string output2 = await p.StandardOutput.ReadToEndAsync();
p.WaitForExit();
// p.WaitForExitAsync(); // 子プロセスが終了するのを待つ こっちだとエラーが出た
p.Dispose(); // 子プロセスの破棄
return output2;
}
}
C#のEdgeJS中身を考察
EdgeJSのC#EdgeCompiler.csを見ることでReadMeに書かれていないやり方で実装方法が発見できます。
NodeJsからパラメーターで送るとC#側でSystem.Runtimeなど処理を自動で読み込んでもらえる。
コンパイル文のC#側でUsingを書く必要がないです。それ以外のアセンブリはreferencesで設定して読み込みます。
上に書かれてないものはreferencesに設定し読み込みます
コンソールアプリの中身はNugetからRestSharpを取得し、データーを取得、Timerが処理を止めてからデータを取得するようにした。
class Program
{
private static Timer MyTimer;
static void Main(string[] args)
{
RestClient client = new RestClient();
RestRequest request = new RestRequest();
// RestAPIから情報取得のためにアクセスする、e-StatのURLです(json用)
client.BaseUrl = new Uri("http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData");
// HTTPのコマンドを指定します、情報の取得なので GET を指定します
request.Method = Method.GET;
// リクエストを送信します
var response = client.Execute(request);
//Thread.Sleep(1000);
Console.WriteLine("--------111-----------------" + response.Content );
// Thread.Sleep(1000);
Console.WriteLine("--------222-----------------" + request.ToString());
// Thread.Sleep(2000);
Console.WriteLine("--------333-----------------");
}
}
コンパイル文のC#で読み込めるアセンブリ
読み込めるアセンブリは制限があります。バージョンの新しいもの(NetStandard2.0以降?)は読み込めないことが多いようです。
読み込めるアセンブリを確認するにはEdgeCompiler.csのcompileAssembliesの値をデバッグするとわかります。
実行結果
コンソールアプリで実行したものをすべて取得してからnode.jsに返ってきました。
続く
↧