I have a simple clientside javascript application. I want it to load a DLL file (for a SwipeReader CR100) and call functions from the DLL library from within the javascript code. The second is to add listeners to events fired by the SwipeReader, like DocumentRead or DocumentReadError and handle them in javascript.
So, I have 4 minor issues to solve:
- Load DLL in javascript (mainly Chrome V8 engine).
- Call function in DLL.
- Add listener to event fired in DLL.
- On callback with response object do something in JS (alert, console.log data)
Has anyone done this before or is this even possible?
Thank you in advance,
Daniel.
I've done it. The solution is to use EdgeJS as a bridge between NodeJS V8 and C# CLR. Edge loads the DLL and creates a communication channel between V8 and CLR, the messages are functions of the form Func<object, Task<object>>
or function(payload, callback)
that are marshalled between each language VM.
I'll post the code sample below:
C#
public abstract class NetWebSocket
{
private Func<object, Task<object>> SendImpl { get; set; }
protected NetWebSocket(Func<object, Task<object>> sendImpl)
{
this.SendImpl = sendImpl;
}
protected abstract Task ReceiveAsync(string message);
public Func<object, Task<object>> ReceiveImpl
{
get
{
return async (input) =>
{
Console.Out.WriteLine(input);
await this.ReceiveAsync((string) input);
return Task.FromResult<object>(null);
};
}
}
protected async Task SendAsync(string message)
{
await this.SendImpl(message);
return;
}
}
public class MyNetWebSocketImpl : NetWebSocket
{
public CHello module;
private string JSONCodelineDataRepr = "not set";
public MyNetWebSocketImpl(Func<object, Task<object>> sendImpl) : base(sendImpl)
{
// do other stuff after calling the super class constructor
module = new CHello();
module.DocumentReadEvent += this.DocumentReadEventHandler;
module.DocumentReadErrorEvent += this.DocumentReadErrorEventHandler;
// uncomment after the websocket communication works
module.Start();
}
protected override async Task ReceiveAsync(string message)
{
// not really needed because only the NodeJS Server listens to C# .NET Server messages
Console.WriteLine(message);
if (message.Equals("shutdown"))
{
module.Close();
}
// not necessary (can comment the send function call)
// if I eventually receive a message, respond with the JSON representation of the Patient ID Card
await this.SendAsync("I received a message from you, but I'll ignore it and send you the Patient" +
" ID Card Data instead.. I'm a fish, so start phishing! PersonData = " +
JSONCodelineDataRepr);
return;
}
private async void DocumentReadEventHandler(string args)
{
this.JSONCodelineDataRepr = args;
await this.SendAsync(args);
}
private async void DocumentReadErrorEventHandler(string args)
{
await this.SendAsync(args);
}
}
public class Startup
{
public static MyNetWebSocketImpl ws;
public async Task<object> Invoke(Func<object, Task<object>> sendImpl)
{
ws = new MyNetWebSocketImpl(sendImpl);
return ws.ReceiveImpl;
}
}
Javascript/NodeJS
(function(e,d,g,e){
var edge = require('edge'),
http = require('http'),
WebSocketServer = require('ws').Server,
swipe = edge.func('./dlls/ActiveXCOM.dll');
var server = http.createServer(function(req,res){
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end((
function () { /*
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id='jsonOutput'>
</div>
<script>
var ws = new WebSocket('ws://' + window.document.location.host);
ws.onmessage = function (event) {
console.log(event.data);
var div = document.getElementById('jsonOutput');
div.innerHTML = event.data;
}
ws.onopen = function (event) {
// send something to the server
ws.send('I am the client from the browser calling you, the NodeJS WebSocketServer!');
}
ws.onclose = function (event) {
alert('websocket closing');
}
window.onbeforeunload = function myonbeforeUnload() {
return "Are you sure?";
}
window.onunload = function myonunload() {
confirm('Are you really sure?');
ws.close();
return "Are you really sure?";
}
</script>
</body>
</html>
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]);
});
var wss = new WebSocketServer({server: server});
wss.on('connection', function(ws) {
var sendImpl = function (message, callback) {
console.log(message);
ws.send(message);
callback();
};
var receiveHandler = swipe(sendImpl, true);
ws.on('message', function (message) {
receiveHandler(message);
});
ws.on('close', function close(){
console.log('****************************The client disconnected!');
receiveHandler('shutdown');
delete receiveHandler;
});
});
server.listen(process.env.PORT || 8080);
module.exports = this;
})();
I hope the implementation is clear. If you have any trouble understanding it, please don't hesitate to write to me.
Happy Coding!
[Don't listen to the naysayers!]
Call functions from the DLL library from within the javascript code.
No. You can't load a DLL inside JavaScript.
Why?
JavaScript is executed in the stack of the browser. To make anything available, you'll have to wire it up with the browser and then make it accessible; too much of work.
Work Around
You can have a client application written in say C# which connects to a JS websocket, then transfer the data. The WebSocket can check for specific chunks of data, and process it the way you want.
I have used it the way I have described in a project using a fingerprint scanner. Works great! If you add a little bit of Crypto, even better!