2013-05-08 37 views
9

Próbuję pobrać aplikację node.js do interakcji z czytnikiem linii papilarnych .NET SDK o nazwie U.are.U. Pakiet SDK udostępnia biblioteki .dll (win32 i x64), Java i .NET. Zdecydowałem się użyć .NET do prostego użycia, mając wszystkie interfejsy gotowe do użycia i wszystko.Czytnik linii papilarnych na węźle.js do .NET SDK

Obecny problem, przed którym stoję, polega na wywołaniu funkcji .NET i zachowaniu asynchronicznej natury node.js. Przepływ aplikacji (na przykładzie .NET) jest dość prosty, 3 wywołania biblioteki i odcisk palca jest wykonywany.

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; 
    } 
} 

Jak mogę to zmienić, aby mogła być użyta w pliku node.js, zamiast programu .NET gui?

Należy również zauważyć, że plik node.js nie zawsze będzie wywoływał funkcję w programie .NET w celu odebrania funkcji. Część identyfikacyjna programu dzieje się asynchronicznie i jest wyłączona, gdy ktoś kładzie palec na czytniku linii papilarnych, co oznacza, że ​​część node.js nie ma pojęcia, kiedy to się stanie. Tak więc nie mogę polegać na ciągłym pytaniu o dane z części .NET, musi wywoływać wywołania zwrotne na node.js bez pytania. W zasadzie jest to komunikacja dwukierunkowa, nie tylko na żądanie, ponieważ żądanie użycia serwera sieciowego byłoby znacznie łatwiejsze.

Znalazłem bibliotekę node.js, która może zamknąć lukę między .NET i node.js o nazwie edge.js, czy może to być pomocne?


Zasadniczo edge.js może działać wraz z node-webkit (które będę żeglugowego moją aplikację), mogę zadzwonić API węzeł bezpośrednio w stronę, więc mogę zaktualizować DOM W zależności od wyniku z biblioteki. Potrzebuję być w stanie zarejestrować zadanie asynchroniczne, które może powiadomić CAN z wewnątrz CLR do odpowiednika node.js przez wyemitowanie zdarzenia lub wywołanie wywołania zwrotnego!

Według autora edge.js można to zrobić łatwo https://github.com/tjanczuk/edge/issues/54#issuecomment-17967082 ja po prostu nie mają wystarczająco dużo umiejętności .NET to zrobić (z pełnego modułu rozwiniętego) ze wszystkich wywołań zwrotnych.

+1

Czy możesz wyjaśnić, dlaczego przesuwasz się tutaj za pomocą pliku node.js? – vittore

+0

Używam węzła webkit, który może wysyłać "przeglądarkę" wraz z węzłem.js wewnątrz i mogę wywoływać węzły API bezpośrednio z tagów skryptów, między nimi jest płynny mostek, a ponieważ będę łączyć ze sobą każdą aplikację (styl P2P), to musi być – pocesar

+0

Możesz chcieć rzucić okiem na Reactive.NET (Rx.NET). Używałem go wcześniej, aby wywoływać wywołania zwrotne, gdy coś się wydarzy, co jest możliwe dzięki koncepcji subskrypcji, podobnie jak w przypadku zdarzeń. – Chris

Odpowiedz

1

Po długim czasie od opublikowania tego pytania, mogę w prosty sposób używać edge.js do komunikowania się WEJŚCIE I WYJŚCIE mojego interfejsu użytkownika .NET (nawet kontrola node.js w węźle-webkit z .NET UI), używając emulatora zdarzeń węzła :

// 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') 

I teraz można nazwać in/out z .NET przy użyciu zdarzenia, zamiast wywoływania kodu macierzystego (które mogą nie być bezpieczne wątek)

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; 

mogą teraz zadzwonić z dowolnego Emit('error', "My error") pochodzi moja klasy od Base asynchronicznie. Zauważ, że niedawno zacząłem pracować w C#, a mój kod przedstawiony tutaj może nie najlepiej pasować.

1

Interesujący problem. Czy byłoby możliwe po prostu upuścić interesującą cię funkcję do pliku ASHX (niestandardowy handler HTTP), a następnie opublikować go w aplikacji twojego węzła? W zależności od tego, co chcesz zwrócić, być może będziesz musiał dokonać serializacji/deserializacji, ale wydaje się, że to najprostszy sposób na wystrzelenie fragmentu kodu C# z aplikacji węzła ....

Microsoft ma piękną dobry zestaw samouczków dotyczących niestandardowych procedur obsługi HTTP, które można znaleźć pod adresem here.

Podstawowy szkielet ashx jest poniżej:

<%@ WebHandler Language="C#" Class="NodeHandler" %> 

using System; 
using System.Web; 

public class NodeHandler : IHttpHandler { 

    public void ProcessRequest (HttpContext context) { 

     //Handle fingerprint stuff!!! 

     context.Response.ContentType = "text/plain"; 
     context.Response.Write("Hello World"); 
    } 

    public bool IsReusable { 
     get { 
      return false; 
     } 
    } 

} 

Można by zastąpić zawartość ProcessRequest ze zmodyfikowaną wersją istniejącej funkcji.

0

Chciałbym utworzyć albo własnym gospodarzem WCF usług (tj usługi Windows, który ma WCF punkt końcowy) lub użyć ramy jak OpenRasta lub ServiceStack zastąpić WCF

We wszystkich trzech przypadkach chciałbym skończyć się o usługę json internetowej, które zwracają wynik ostatniego wywołania do CaptureAndExtractFmd

Następnie chciałbym skonsumować tę usługę w węźle.js

Jeśli potrzebujesz dalszych informacji w wybrany przez siebie sposób, po prostu utwórz kolejne pytanie.

Przykładowy kod z WCF, C# część

[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 część

var request = require("request"); 

request.get("baseaddress/GetLastFeature", function (err, res, body) { 
    if (!err) { 
     var resultsObj = JSON.parse(body);   
     console.log(resultsObj); 
    } 
}); 
1

Korzystanie z tej biblioteki .NET SDK nie jest odpowiednim rozwiązaniem dla tego problemu.

Sam Node.js to aplikacja w języku C++, a próba prawidłowego użycia biblioteki .NET jest po prostu pytaniem o świat zranienia, szczególnie jeśli chodzi o , zwłaszcza, gdy SDK udostępnia również natywną bibliotekę C/C++!

Oczywiście nie można po prostu użyć biblioteki C++ bezpośrednio; będziesz musiał napisać opakowanie C++. W świecie węzłów są one znane jako addons. Pisanie addonu nie jest proste, ale nawet ktoś mający niewielkie doświadczenie w C++ powinien umieć śledzić przykłady w dokumentacji i uzyskać coś działającego.

Uzyskanie rodzimego dodatku zbudowanego w systemie Windows może również być nieco trudne; here's some tips to help you get started.

Ponieważ pakiet SDK, którego używasz, znajduje się za zaporą, nie mogę podać żadnych konkretnych przykładów. Jednak wyobrażam sobie, że twój obiekt opakowujący C++ ujawni kilka metod, a także napiszę wokół niego opakowanie JS, aby odsłonić czysty interfejs API. Na przykład:

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 

Teraz aplikacja może po prostu:

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

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

Ten przykład wyraźnie pomija dużo, ale powinno dać dobry pomysł, co musi się zdarzyć na końcu JS rzeczy. Jeśli chodzi o wykrywanie, kiedy palec jest umieszczony na czytniku, znowu nie mogę powiedzieć, jak to zrobisz bez dostępu do SDK. Założę się, że gdzieś skończysz sondować. Powinno to zostać wykonane w osobnym wątku w twoim dodatku.


Bonus: dzieje natywnej trasy oznacza, że ​​będziesz prawdopodobnie również kompatybilny z wersją Linux SDK, więc aplikacja będzie również działać na Linuksie!

+0

Nie mogę wywołać kodu węzła z wewnątrz opakowania C++, tak czy inaczej. Wygląda na to, że można to zrobić za pomocą edge.js i wtyczki kodu .NET – pocesar

+0

@ Oczywiście: możesz. Zobacz [przykład wywołania zwrotnego] (http://nodejs.org/api/addons.html#addons_callbacks). – josh3736

+0

wydaje się być bardzo skomplikowany w porównaniu do rozwiązania edge.js ... wydaje się wymagać zaawansowanej wiedzy C++, której mi brakuje. – pocesar