Open gentlecolder opened 9 years ago
I tried many times as read the instruction: Func<object, Task
delegate tag can not submit above "Func<object, Task
the erro is cannot wait System.Func<object,System.
Threading.Tasks.Task
I and i saw .net can handle node events, but node can not handle .net events, that's not fair.
@gentlecolder The functions Edge.js can marshal from JavaScript to C# must have the following signature:
function (data, callback) {
// ...
callback(error, result);
}
These functions will then have the shape of the following delegate on the C# side:
Func<object, Task<object>>
If you plan to hook up JavaScript function as a .NET event handler, you will need to provide a wrapper event handler implementation around the marshaled Func<object,Task<object>>
in C#.
The debug complied error is:
System.Func<ob
tem.Threading.Tasks.Task
then i changed the Func<object,Task
node Code C# CODE
it seamed that the node function can not changed to Eventhandler implicitly, why? doest that means Eventhandler is not a function in C#. I am not good at C#
Edge.js does not marshal arbitrary functions between JavaScript and .NET, the functions must be of appropriate signature. It means that in most cases you will need to write an adapter code or class that changes the intended signature of the function: https://github.com/tjanczuk/edge#how-to-integrate-c-code-into-nodejs-code.
In your case, I believe you need to write a wrapper around *EventHandler type expected in your C# code and the Func<object,Task<object>>
exposed by Edge.
above code i have showed wrapped still cannot pass complie
@tjanczuk Could you please provide a simple example of EdgeJS code (Node.JS) code handling .NET events properly?
I want to start an ID Card Reader application (for 3M CR100 SwipeReader) and I want my (edgejs + nodejs) code to listen to the DocumentReadEvent and DocumentReadErrorEvent from my C# code.
I hope you see this asap.
Please reply to this comment just to see you have seen it and if you can apply some action to this issue commented here.
With all due respect, Daniel.
@gentlecolder have you been able to assign a javascript event handler to a C# event?
@danielmihai Are you writing .NET application or a Node.js application (i.e. is Node hosted in CLR or vice versa)?
Have a look at https://github.com/tjanczuk/edge/blob/master/samples/209_websocket.js, specifically at how the sendImpl
(https://github.com/tjanczuk/edge/blob/master/samples/209_websocket.js#L79) is set up and used to call back to Node.js when something happens in CLR. This example assumes you write a Node.js app and host CLR in it, but the pattern is also applicable if the reverse is true.
@tjanczuk I want to send a function from JavaScript that acts as an event handler to the c# dll. In c# the invoke function receives a dynamic input as a JavaScript object with the javascript handler function { handleCSeventEventHandler: function(data, callback) { // do something with data (i don't know what data is in this case, most probably the event) callback(error, result); } }
In c# on Invoke, I'll assign the EventHandler to the Event:
public EventHandler DocumentReadEvent; public SwipeReader swipeReader;
.... Invoke (dynamic input) {
this.swipeReader = new SwipeReader(); this.swipeReader.Start();
this.DocumentReadEvent += input.handleCSeventEventHandler;
}
The scenario I'm in : I've written a library that initializes a 3M CR100 SwipeReader, starts listening for SwipeReader events, it uses a Control to invoke event processing (if _threadHelperControl.invokeRequired then _threadHelperControl.invoke(ProcessEvent), I'll post the code below:
private void ProcessEventThreadHelper(MMM.Readers.FullPage.EventCode aEventCode) { try { if (_threadHelperControl.InvokeRequired) { _threadHelperControl.Invoke( new MMM.Readers.FullPage.EventDelegate(ProcessEvent), new object[] {aEventCode} ); } else { ProcessEvent(aEventCode); } } catch (Exception ) { Console.Out.Write("thread helper control failed to invoke ProcessEvent"); } }
private void ProcessEvent(MMM.Readers.FullPage.EventCode aEventCode) { InsertRow((int)aEventCode, aEventCode.ToString(), 0, string.Empty, RowType.Event);
if (aEventCode == EventCode.DATA_READ)
{
if (DocumentReadEvent != null)
{
this.DocumentReadEvent(this.resultStr);
}
}
}
In InitializeSwipeAPI i have private int InitialiseSwipeAPI() { MMM.Readers.ErrorCode lErrorCode = MMM.Readers.ErrorCode.NO_ERROR_OCCURRED;
// Initialise logging and error handling first. The error
handler callback // will receive all error messages generated by the 3M Page Reader SDK MMM.Readers.Modules.Reader.SetErrorHandler( new MMM.Readers.ErrorDelegate(ProcessErrorThreadHelper), IntPtr.Zero ); lErrorCode = MMM.Readers.Modules.Reader.InitialiseLogging( true, 3, -1, "SwipeReader.Net.log" );
if (lErrorCode == MMM.Readers.ErrorCode.NO_ERROR_OCCURRED)
{
// Next load the settings for the Swipe Reader from the ini
files. You can // also modify and save settings back to the ini files using // MMM.Readers.Modules.Reader.SaveSwipeSettings() lErrorCode = MMM.Readers.Modules.Reader.LoadSwipeSettings( ref swipeSettings );
}
if (lErrorCode == MMM.Readers.ErrorCode.NO_ERROR_OCCURRED)
{
// Initialise the Swipe Reader. Data and events will be
sent back in a // non-blocking fashion through the callbacks provided // // Thread helper delegates are used to avoid thread-safety issues, // particularly with .NET framework 2.0 lErrorCode = MMM.Readers.Modules.Swipe.Initialise( swipeSettings, new MMM.Readers.Modules.Swipe.DataDelegate(ProcessDataThreadHelper), new MMM.Readers.FullPage.EventDelegate(ProcessEventThreadHelper) ); }
if (lErrorCode != MMM.Readers.ErrorCode.NO_ERROR_OCCURRED)
{
InsertRow(
(int)lErrorCode,
lErrorCode.ToString(),
0,
"Failed to initialise Swipe Reader API",
RowType.Error
);
return (int)lErrorCode;
}
return 1; }
How can I keep the DLL alive in nodejs so that it continually runs and listens for event triggering from the CR100 SwipeReader? How can I assign a function from nodejs to c# eventhandler to handle the event? How can the CLR communicate with v8 to send the event to my nodejs module?
Kind Regards, Daniel.
On 21 ian. 2016, at 22:27, Tomasz Janczuk notifications@github.com wrote:
Have a look at https://github.com/tjanczuk/edge/blob/master/samples/209_websocket.js, specifically at how the sendImpl ( https://github.com/tjanczuk/edge/blob/master/samples/209_websocket.js#L79) is set up and used to call back to Node.js when something happens in CLR. This example assumes you write a Node.js app and host CLR in it, but the pattern is also applicable if the reverse is true.
— Reply to this email directly or view it on GitHub https://github.com/tjanczuk/edge/issues/330#issuecomment-173698254.
This line of code will require some extra work:
this.DocumentReadEvent += input.handleCSeventEventHandler;
The input.handleCSeventEventHandler
is of type Func<object,Task<object>>
and as such will need to be wrapped in an adapter class that is of type expected by DocumentReadEvent
. Within this wrapper class you will also likely need to covert the actual event data into a structure that can be passed as an object to handleCSeventEventHandler
. It can be an anonymous object. You may also find out that passing the event directly works, but I would not count on that.
Hi @tjanczuk ,
I managed to get it working by integrating this example https://github.com/tjanczuk/edge/blob/master/samples/209_websocket.js and sending the function to the DLL.
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;
}
}
(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;
})();
This kind of does what it should. Thank you very very much!
My new question arises if this can be done without this abstractified websocket connection, just by giving the invoke a function(input, callback) { //do something; callback(error, result); } and the edgejs func returns a Func<object, Task
^:)^ There are no words to thank you enough!
Would you like to include this example of handling C# events in Javascript (Node) to the samples folder? I would be glad to offer the full implementation to have a mini contribution to EdgeJS (Samples only, for now, who knows what might happen in the future), if you agree :D.
@tjanczuk Another question popped into my mind, if it's possible to convert this into a client-side javascript module and have things packed like nw.js does ? What do you think?
Thank you again for your support, examples and wonderful library! ^:)^ :bow:
@tjanczuk Any news?
Hi @danielmihai , can I ask, if you solved this your situation? I deal with a similar problem as you, only I need to handle C# events from RFID reader.
Thanks for a reaction.
If you keep the same pattern as in the example I've written, it doesn't matter what you expose. Keep the same pattern.
@danielmihai , Hi, how did you get your swipe reader working. I'm working with my fingerprint scanner but no luck in listening for events. Thanks for you responce. ` // Activate capture handler
currentReader.On_Captured += new `Reader.CaptureCallback(OnCaptured);
`
I would first make a test program in c#, then adapt it to work for edge, then write the DLL I really need for my app
Daniel M. Colceag
On 20 Apr 2017, at 13:26, Daryll Tee notifications@github.com wrote:
@danielmihai , Hi, how did you get your swipe reader working. I'm working with my fingerprint scanner but no luck in listening for events. Thanks for you responce. // Activate capture handler currentReader.On_Captured += newReader.CaptureCallback(OnCaptured);``
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
the problem code is bellow: /the edge code bellow: edged.js/ var stractData = edge.func(function () {/*
*/});
module.exports.stractData=stractData;
/the nodejs code bellow:/ var databox=require('edged.js');
var util = require('util');
var input = { DataChangedHandler: function (object sender, IList e) {
foreach (DataMonitorValueChangedArgs monitorValue in e)
{
};
databox.stractData(input);
is there any good solution ?