Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
309 views
in Technique[技术] by (71.8m points)

c# - Call Function from DLL loaded in front-end javascript (load dll in clientside javascript)

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:

  1. Load DLL in javascript (mainly Chrome V8 engine).
  2. Call function in DLL.
  3. Add listener to event fired in DLL.
  4. 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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!]


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...