{ Act I }
{ Act II }
skip to act I | skip to act II
Brought to you by Tomasz Janczuk / @tjanczuk
(Use space or arrow keys to navigate)
Call C# async lambda from Node.js
var edge = require('edge');
var hello = edge.func(function () {/*
async (input) => {
return ".NET welcomes " + input.ToString();
}
*/});
hello('Node.js', function (error, result) {
if (error) throw error;
console.log(result);
});
see full code
> node sample.js
.NET welcomes Node.js
Call Node.js functions from .NET
using EdgeJs;
public static async void Start()
{
var func = Edge.Func(@"
return function (data, cb) {
cb(null, 'Node.js ' + process.version + ' welcomes ' + data);
}
");
Console.WriteLine(await func(".NET"));
}
read more
> sample.exe
Node.js v0.10.28 welcomes .NET
Async, in-process calling convention between CLR and Node.js
Node.js and .NET ecosystems
JavaScript with C#, F#, Python, Lisp, and PowerShell
loose typing with strong typing
IO-bound single threaded with CPU-bound multi-threaded
cool with awesome
on Windows, MacOS, and Linux
Call C# async lambda from Node.js
var edge = require('edge');
var hello = edge.func(function () {/*
async (input) => {
return "CSharp welcomes " + input.ToString();
}
*/});
hello('Node.js', function (error, result) {
if (error) throw error;
console.log(result);
});
see full code
> node sample.js
CSharp welcomes Node.js
Call F# async workflows from Node.js
var edge = require('edge');
var hello = edge.func('fs', function () {/*
fun input -> async {
return "FSharp welcomes " + input.ToString()
}
*/});
hello('Node.js', function (error, result) {
if (error) throw error;
console.log(result);
});
how to F# in Node.js
$> node sample.js
FSharp welcomes Node.js
Script IronPython from Node.js
var edge = require('edge');
var hello = edge.func('py', function () {/*
def hello(input):
return "Python welcomes " + input
lambda x: hello(x)
*/});
hello('Node.js', function (error, result) {
if (error) throw error;
console.log(result);
});
how to python in Node.js
$> node sample.js
Python welcomes Node.js
Access MS SQL from Node.js using in-process ADO.NET
var update = require('edge').func('sql', function () {/*
update Products
set ProductName = @newName
where ProductId = @id
*/});
update({ id: 10, newName: 'New Ikura' }, function (error, result) {
if (error) throw error;
console.log(result);
});
how to T-SQL in Node.js
Call PowerShell scripts asynchronously from Node.js (Windows only)
var edge = require('edge');
var hello = edge.func('ps', function () {/*
"PowerShell welcomes $inputFromJS"
*/});
hello('Node.js', function (error, result) {
if (error) throw error;
console.log(result);
});
how to PowerShell in Node.js
c:\projects\edgedemo> node sample.js
PowerShell welcomes Node.js
Call Lisp from Node.js
var edge = require('edge');
var factorial = edge.func('lsharp', function () {/*
(def fact(n)
(if (is n 0) 1 (* n (fact (- n 1)))))
*/});
factorial([5], function (error, result) {
if (error) throw error;
console.log(result);
});
edge-lsharp extension by @richorama
c:\projects\edgedemo> node sample.js
120
Extend Edge.js with other CLR/Mono languages or DSLs
var helloCs = edge.func(...); // C# is the default
var helloFs = edge.func('fs', ...); // F#
var helloPy = edge.func('py', ...); // Python
var helloFo = edge.func('foo', ...); // Your CLR/Mono language or DSL here
learn more
Call a method from existing CLR library
var hello = require('edge').func({
assemblyFile: 'My.Edge.Samples.dll',
typeName: 'Samples.FooBar.MyType',
methodName: 'MyMethod' // Func<object,Task<object>>
}});
hello('Node.js', function (error, result) { ... });
how to integrate CLR code
Compile source code on the fly
var hello = edge.func(
'async (input) => { return "C# welcomes " + input.ToString(); }'
);
how to integrate CLR code
Embed multi-line source code inline
var hello = edge.func(function () {/*
async (input) => {
return "C# welcomes " + input.ToString();
}
*/});
how to integrate CLR code
Compile source code from a file
var hello = edge.func('mysample.cs');
how to integrate CLR code
Compile code for many CLR languages or DSLs through extensibility
var helloCs = edge.func(...); // C# is the default
var helloFs = edge.func('fs', ...); // F#
var helloPy = edge.func('py', ...); // Python
var helloPs = edge.func('ps', ...); // PowerShell
var helloPs = edge.func('sql', ...); // T-SQL via ADO.NET
...
how to support other CLR languages or DSLs
Source code may be an async lambda expression or class library
var helloLambda = edge.func(function () {/*
async (input) => { return "C# welcomes " + input.ToString(); }
*/});
var helloClass = edge.func(function () {/*
using System.Threading.Tasks;
public class Startup {
public async Task<object> Invoke(object input) {
return ".NET welcomes " + input.ToString();
}
}
*/});
how to integrate CLR code
Use C# dynamics to access objects passed from JavaScript
var hello = edge.func(function () {/*
async (dynamic input) => {
return input.nested.text + " work!";
}
*/});
var input = {
nested: {
text: "Dynamics"
}
};
hello(input, function (error, result) { ... });
Reference libraries and import namespaces within script
var accessSql = edge.func(function () {/*
#r "System.Data.dll"
using System.Data;
async (input) => {
...
}
*/});
Call CLR functions synchronously or asynchronously
var hello = edge.func(...);
// Make asynchronous call
hello('Node.js', function (error, result) {
...
});
// Make synchronous call
// Requires CLR function to return completed Task<object>
var result = hello('Node.js', true);
how to integrate CLR code
Use Visual Studio to debug C# code running in node.exe
Pass data from Node.js to C#
var hello = require('edge').func('My.Sample.dll');
var payload = {
anInteger: 1,
aNumber: 3.1415,
aString: 'foobar',
aBool: true,
anObject: { first: 'Tomasz', last: 'Janczuk' },
anArray: [ 'a', 1, true ],
aBuffer: new Buffer(1024)
}
hello(payload, function (error, result) { ... });
see full code
Pass data from C# to Node.js
var getData = require('edge').func(function () {/*
async (input) => {
return new {
anInteger = 1,
aNumber = 3.1415,
aBool = true,
anObject = new { a = "b", c = 12 },
anArray = new object[] { "a", 1, true },
aPerson = new Person("Tomasz", "Janczuk"),
aBuffer = new byte[1024]
};
}
*/});
getData(null, function (error, result) { ... });
see full code
Node.js function is also data
var addAndMultiplyBy2 = require('edge').func( ... );
var payload = {
a: 2,
b: 3,
timesTwo: function(input, callback) {
callback(null, input * 2);
}
};
addAndMultiplyBy2(payload, function (error, result) { ... });
see full code
Node.js function is also data, continued
var addAndMultiplyBy2 = require('edge').func(function () {/*
using ...;
async (dynamic data) => {
int sum = (int)data.a + (int)data.b;
var timesTwo = (Func<object,Task<object>>)data.timesTwo;
return await timesTwo(sum);
}
*/});
see full code
C# function is also data
var createHello = require('edge').func(function () {/*
async (input) => {
return (Func<object,Task<object>>)(async (i) => {
Console.WriteLine("Hello from .NET");
return null;
});
}
*/});
var hello = createHello(null, true);
hello(null, true); // prints out "Hello from .NET"
see full example
Call Node.js proxy to C# closure over CLR data
var createCounter = require('edge').func(function () {/*
async (input) => {
var k = (int)input; // CLR state
return (Func<object,Task<object>>)
(async (i) => { return ++k; });
}
*/});
// create counter with initial state of 12
var counter = createCounter(12, true);
console.log(counter(null, true)); // prints 13
console.log(counter(null, true)); // prints 14
see full example
Latency of Edge.js call is 32x smaller than localhost, cross-process call over HTTP
var update = require('edge').func('sql', function () {/*
update Products
set ProductName = @newName
where ProductId = @id
*/});
update({ id: 10, newName: 'New Ikura' }, function (error, result) {
if (error) throw error;
console.log(result);
});
how to T-SQL in Node.js
#r "System.Data.dll"
#r ...
using System.Data;
using ...
public class Startup {
public async Task<object> Invoke(string command) {
string connectionString = ...;
using (var conn = new SqlConnection(connectionString)) {
using (var command = new SqlCommand(commandString, conn)) {
await connection.OpenAsync();
using (var reader = await command.ExecuteReaderAsync() {
...
full article
by
David Neal (@reverentgeek)
Run CPU-bound background work on CLR thread pool
var heavyLifting = require('edge').func(function () {/*
async (input) => {
// we are on V8 thread here
return await Task.Run<object>(async () => {
// we are on CLR thread pool thread here
await Task.Delay(5000); // simulate CPU bound
return ".NET welcomes " + input.ToString();
});
}
*/});
heavyLifting('Node.js', function (error, result) { ... });
see full code
Use Windows authentication to authenticate calls to your Node.js HTTP server
var authenticate = require('edge').func(function() {/*
class Startup {
[DllImport("advapi32.dll")] static extern bool LogonUser(...);
public async Task<object> Invoke(dynamic i) {
IntPtr t;
return Startup.LogonUser(i.user, null, i.password, 3, 0, out t))
}
}
*/});
authenticate({
user: 'tjanczuk@redmond.corp.microsoft.com',
password: 'foobar'
}, function (error, result) { ... });
see full code
Compress files and folders using .NET 4.5 ZIP compression
var zip = require('edge').func(function() {/*
class Startup {
public async Task<object> Invoke(dynamic p) {
await Task.Run(async () => {
System.IO.Compression.ZipFile.CreateFromDirectory(
(string)p.src, (string)p.dest);
});
return null;
}
}
*/});
zip({ src: '..\\mydir', dest: '..\\mydir.zip' }, function (error) {
...
});
see full code
Convert images between JPG, BMP, TIFF, PNG, and GIF
var convertImageToJpg = require('edge').func(function() {/*
#r "System.Drawing.dll"
using System.Drawing;
async (src) => {
await Task.Run(async () => {
Image.FromFile(src).Save((string)src + ".jpg", ImageFormat.Jpeg);
});
return null;
}
*/});
convertImageToJpg('.\\edge.png', function (error) { ... });
see full code
Plug in .NET OWIN apps as connect middleware or express handlers
var owin = require('connect-owin')
, express = require('express');
var app = express();
app.get('/net', owin('Edge.Samples.dll'));
app.get('/node', function (req, res) {
res.send(200, 'Hello from JavaScript!');
});
app.listen(3000);
bbaia/connect-owin
Use WCF to call SOAP services
var edge = require('edge');
var kg2pound = edge.func('soap.csx');
kg2pound(123, function (error, result) { ... });
see full code
Use WCF proxy to call a SOAP service; soap.csx:
// ...
public class Startup {
public async Task<object> Invoke(double kilograms) {
var client = new ConvertWeightsSoapClient(
new BasicHttpBinding(),
new EndpointAddress(
"http://www.webservicex.net/ConvertWeight.asmx"));
return await client.ConvertWeightAsync(
kilograms, WeightUnit.Kilograms, WeightUnit.PoundsTroy);
}
}
see full code
Asynchronously call Node.js functions in .NET
using EdgeJs;
var func = Edge.Func(@"
return function (data, cb) {
cb(null, 'Node.js ' + process.version + ' welcomes ' + data);
}
");
Console.WriteLine(await func(".NET"));
more
Core Node.js modules are included with Edge.js
using EdgeJs;
async void Start() {
var createHttpServer = Edge.Func(@"
var http = require('http');
return function (port, cb) {
http.createServer(function (req, res) {
res.end('Hello, world! ' + new Date());
}).listen(port, cb);
};
");
await createHttpServer(8080);
}
more
Additional Node.js modules can be installed from NPM
> npm install ws ... ws@0.4.31 node_modules\ws
using EdgeJs;
var createWebSocketServer = Edge.Func(@"
var WebSocketServer = require('ws').Server;
return function (port, cb) {
var wss = new WebSocketServer({ port: port });
wss.on('connection', function (ws) { /* ... */ });
cb();
};
");
more
Wrap Node.js state in a closure
using EdgeJs;
var increment = Edge.Func(@"
var current = 0;
return function (data, callback) {
current += data;
callback(null, current);
}
");
Console.WriteLine(await increment(4)); // outputs 4
Console.WriteLine(await increment(7)); // outputs 11
more
using EdgeJs;
var createServer = Edge.Func(@"
var http = require('http');
return function (port, cb) {
var server = http.createServer(...);
cb(null, function (data, cb) {
server.close(); cb();
});
}
");
var closeServer = (Func<object,Task<object>>)await createServer(8080);
// ...
await closeServer(null);
more
var onMessage = async (msg) => { return ((string)msg).ToUpper(); };
var createWebSocketServer = Edge.Func(@"
var WebSocketServer = require('ws').Server;
return function (params, cb) {
var wss = new WebSocketServer({ port: params.port });
wss.on('connection', function (ws) {
ws.on('message', function (msg) {
params.onMessage(msg, function (error, res) { ws.send(res); });
});
});
cb();
};");
await createWebSocketServer(new { port = 8080, onMessage = onMessage });
more
Brought to you by Tomasz Janczuk / @tjanczuk
npm install edge
Collaboration welcome