Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fingerprint reader on node.js through .NET SDK

I'm trying to get a node.js app to interact with a .NET SDK fingerprint reader called U.are.U. The SDK provides .dll (win32 and x64), Java and .NET libraries. I decided to use .NET for the simple of use, having all the interfaces ready to use and all.

So, the current problem I'm facing is how to call those .NET functions and still preserve the asynchronous nature of node.js. The application flow (on the .NET example) is pretty straight forward, 3 calls on the library, and the fingerprint is done.

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

How can I change it so it can be usable in node.js, instead of a .NET gui program?

It also need to be noted that the node.js isn't always going to call a function on the .NET program to receive a function. The identification part of the program happens asynchronously and is set off when someone places a finger on the fingerprint reader, that means that the node.js part have no idea when that is going to happen. So I cannot rely on asking data on the .NET part all the time, it must call callbacks on the node.js without having been asked. So basically, it's a bidirectional communication, not only on request, since requesting using a webserver would be much easier.

I've found a node.js library that can close the gap between .NET and node.js called edge.js would this be of any help?


Basically, edge.js can make it work, along with node-webkit (which I'll be shipping my app), I can call the node APIs directly in the page, so I can update the DOM depending on the result from the library. I need to be able to register an async task that CAN notify from inside the CLR to the node.js counterpart either by emitting an event or calling a callback!

According to the edge.js author it can be done easily https://github.com/tjanczuk/edge/issues/54#issuecomment-17967082 I just don't have enough .NET skills to do so (from a full fledged module) with all the callbacks.

like image 588
pocesar Avatar asked May 08 '13 00:05

pocesar


2 Answers

Using this SDK's .NET library is not the appropriate solution for this problem.

Node.js itself is a C++ app, and trying to use a .NET library properly is just asking for a world of hurt, especially when the SDK also provides a native C/C++ library!

Of course, you can't just use the C++ library directly; you'll have to write a C++ wrapper. In the node world, these are known as addons. Writing an addon isn't exactly simple, but even someone with little C++ experience should be able to follow the examples in the documentation and get something working.

Getting a native addon built in Windows can also be a little tricky; here's some tips to help you get started.

Since the SDK you're using is behind a paywall, I can't provide any specific examples. However, I imagine your C++ wrapper object will expose a few methods, and you'll also write a JS wrapper around that to expose a clean API. For example:

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

Now your app can just:

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

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

This example obviously glosses over a lot, but should give you a good idea of what needs to happen on the JS end of things. As far as detecting when a finger is placed on the reader, again, I can't really say how you'll do that without access to the SDK. I'd bet that you'll end up polling somewhere. This should be done on a separate thread in your addon.


Bonus: going the native route means you'll probably also be compatible with the SDK's Linux version, so your app will also work on Linux!

like image 76
josh3736 Avatar answered Oct 09 '22 04:10

josh3736


After a long time since this question was posted, I can use edge.js easily to communicate IN and OUT my .NET UI (even control node.js within node-webkit from .NET UI), using node event emitter:

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

And now you can call in/out from .NET using events, instead of calling native code (that might not be thread safe)

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;

can now call Emit('error', "My error") from anywhere my derived classes from Base, asynchronously. Just notice that I recently started dwelving in C#, and my code presented here might not be the best fit.

like image 36
pocesar Avatar answered Oct 09 '22 04:10

pocesar