10

U.are.U と呼ばれる .NET SDK 指紋リーダーと対話する node.js アプリを取得しようとしています。SDK は、.dll (win32 および x64)、Java、および .NET ライブラリを提供します。.NET を使用することに決めたのは、すべてのインターフェイスをすぐに使用できるようにして、簡単に使用できるようにするためです。

したがって、私が直面している現在の問題は、これらの .NET 関数を呼び出しながら、node.js の非同期性を維持する方法です。アプリケーション フロー (.NET の例) は非常に単純で、ライブラリを 3 回呼び出すだけでフィンガープリントが完了します。

private IEnumerable<Fmd> CaptureAndExtractFmd()
{
    while (!reset)
    {
        DataResult<Fmd> resultConversion;

        try
        {
            if (count >= 8)
            {
                SendMessage("Enrollment was unsuccessful.  Please try again.");
                count = 0;
                break;
            }

            Fid fid = null;
            if (!_sender.CaptureFinger(ref fid))
                break;

            if (fid == null)
                continue;

            count++;

            resultConversion = FeatureExtraction.CreateFmdFromFid(fid, Constants.Formats.Fmd.ANSI);

            SendMessage("A finger was captured.  \r\nCount:  " + (count));

            if (resultConversion.ResultCode != Constants.ResultCode.DP_SUCCESS)
                break;
        }
        catch (Exception)
        {
            break;
        }

        yield return resultConversion.Data;
    }
}

.NET gui プログラムの代わりに node.js で使用できるように変更するにはどうすればよいですか?

また、node.js が常に .NET プログラムの関数を呼び出して関数を受け取るとは限らないことにも注意する必要があります。プログラムの識別部分は非同期で発生し、誰かが指紋リーダーに指を置くと開始されます。つまり、node.js 部分はそれがいつ起こるかわかりません。そのため、常に .NET 部分でデータを要求することに頼ることはできません。要求されずに node.js でコールバックを呼び出す必要があります。したがって、基本的には、要求時だけでなく双方向通信です。Web サーバーを使用した要求の方がはるかに簡単だからです。

edge.jsと呼ばれる .NET と node.js の間のギャップを埋めることができる node.js ライブラリを見つけましたが、これは役に立ちますか?


基本的には、edge.jsで動作させることができ、node-webkit (アプリを出荷する予定です) とともに、ノード API をページで直接呼び出すことができるため、ライブラリからの結果に応じて DOM を更新できます。 . イベントを発行するか、コールバックを呼び出すことによって、CLR 内から node.js の相手に通知できる非同期タスクを登録できる必要があります。

edge.js の作成者によると、簡単に実行できます https://github.com/tjanczuk/edge/issues/54#issuecomment-17967082私はそれを行うのに十分な .NET スキルを持っていません (本格的なモジュールから) ) すべてのコールバックで。

4

4 に答える 4

2

この SDK の .NET ライブラリを使用することは、この問題の適切な解決策ではありません。

Node.js 自体は C++ アプリであり、.NET ライブラリを適切に使用しようとすることは、特にSD​​K がネイティブ C/C++ ライブラリも提供する場合、ただの苦痛を要求するだけです!

もちろん、C++ ライブラリを直接使用することはできません。C++ ラッパーを作成する必要があります。ノードの世界では、これらはアドオンとして知られています。アドオンの作成は単純ではありませんが、C++ の経験がほとんどない人でも、ドキュメントの例に従って何かを機能させることができるはずです。

Windows に組み込まれているネイティブ アドオンを取得するのも少し難しい場合があります。始めるのに役立つヒントをいくつか紹介します

使用している SDK はペイウォールの背後にあるため、具体的な例を提供することはできません。ただし、あなたの C++ ラッパー オブジェクトはいくつかのメソッドを公開すると思います。また、その周りに JS ラッパーを記述して、クリーンな API を公開することもあると思います。例えば:

var uareu = require('./uareu.node') // the native C++ addon dll
    , events = require('events')
    , util = require('util');

function FingerprintReader() {
    events.EventEmitter.call(this); // initialize the EventEmitter

    // do stuff with the native module

    // whenever a finger is placed on the reader:
    this.emit('finger', { id: idFromSdk });
}

util.inherits(FingerprintReader, events.EventEmitter); // we want this module
                                                       // to be an EventEmitter

module.exports = FingerprintReader; // export for require()ing in your app

これで、アプリは次のことができます。

var FingerprintReader = require('fingerprint')
    , fp = new FingerprintReader();

fp.on('finger', function(d) {
    // do something with `d.id`
});

この例は明らかに多くのことを説明していますが、JS 側で何が起こる必要があるかについての良いアイデアを提供するはずです。リーダーに指が置かれたことを検出する限り、SDK にアクセスしないとどのようにそれを行うかはわかりません。どこかで投票することになると思います。これは、アドオンの別のスレッドで行う必要があります。


おまけ:ネイティブ ルートに進むということは、SDK の Linux バージョンとも互換性がある可能性が高いことを意味するため、アプリは Linux でも動作します!

于 2013-05-15T19:56:58.153 に答える
2

この質問が投稿されてから長い時間が経ちましたが、ノード イベント エミッターを使用して、edge.js を使用して .NET UI のインとアウトを簡単に通信できます (.NET UI から node-webkit 内の node.js を制御することさえできます)。

// demo basic code in node.js

var 
  edge = require('edge'), 
  Bridge = edge.func('../path/to/compiled.dll'),
  callback,
  ev = new require('events').EventEmitter();

ev.on('acquire', function(fingerdata){
  console.log(fingerdata);
});

ev.on('error', function(){
}); 

callback = function(event, report){
  // report the result of the event emitter back to .NET
  // you can even pass the "report" to the event handler, so you can return anything you want back to .NET, not just a boolean
  report(null, ev.emit(event.name, event.data));
  //ev.emit(event.name, {data: event.data, report: report});
};

var bridge = Bridge(callback, true);

// calling bridge(null, true); "releases" my device, should be called on process.on('exit')

また、ネイティブ コードを呼び出す代わりに、イベントを使用して .NET から in/out を呼び出すことができるようになりました (これはスレッド セーフではない可能性があります)。

namespace Bridge
{
    public class Startup
    {
        public async Task<object> Invoke(Func<object, Task<object>>callback)
        {
            Bridge.Base.setCallback(callback);

            MainForm mainForm = new Bridge.MainForm();

            Task.Run(async () =>
            {
                Application.Run(mainForm);
            });

            return (Func<object, Task<object>>)(async (i) => { Bridge.Base.release(); return null; });
        }
    }
}

// inside Bridge.Base


static public void setCallback(Func<object, Task<object>> cb)
{
    if (callback == null)
    {
        callback = cb;
    }
}

static public async void Emit(string name, object data)
{
    return await Task.Run(async () =>
    {
        return await callback(new {
            name = name,
            data = data
        });
    });
}

static public Func<object, Task<object>> callback = null;

Emit('error', "My error")から派生したクラスをBase非同期的にどこからでも呼び出せるようになりました。私は最近 C# を使い始めましたが、ここに示すコードは最適ではない可能性があります。

于 2014-01-23T19:50:25.003 に答える
0

セルフホステッド WCF サービス (つまり、wcf エンドポイントを持つ Windows サービス) を作成するか、OpenRasta や ServiceStack などのフレームワークを使用して WCF を置き換えます。

3つのケースすべてで、最後の呼び出しの結果を返すjson Webサービスを持つことになりますCaptureAndExtractFmd

次に、node.js でそのサービスを使用します。

決定した方法についてさらに情報が必要な場合は、別の質問を作成してください。

WCF、C# 部分を使用したサンプル コード

[ServiceContract]
public interface IFingerprintContrat {

   [OperationContract]
   Fmd[] GetLastFeature(); 

}

public class FingerprintService {
  Fmd[] GetLastFeature() {
     return CaptureAndExtractFmd().ToArray()
  }
}

using (ServiceHost host = new ServiceHost(typeof(FingerprintService), baseAddress))
{
// Enable metadata publishing.
  ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
  smb.HttpGetEnabled = true;
  smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
  host.Description.Behaviors.Add(smb);
  host.Open();

  Console.WriteLine("The service is ready at {0}", baseAddress);
  Console.WriteLine("Press <Enter> to stop the service.");
  Console.ReadLine();

  // Close the ServiceHost.
  host.Close();
}

Node.js 部分

 var request = require("request");

 request.get("baseaddress/GetLastFeature", function (err, res, body) {
   if (!err) {
      var resultsObj = JSON.parse(body);         
      console.log(resultsObj);
   }
 });
于 2013-05-11T00:07:09.547 に答える