"It's just a software issue"- Edge.js brings Node and .NET together on three platforms
There was an engineer I used to work with who always said "That's just a software issue." No matter how complex the issue, no matter how daunting, they were confident it could be solved with software.
.NET and C# and NuGet and the community have been making some amazing stuff in the last few years like ScriptCS, Chocolately, Boxstarter. Azure Websites now supports ASP.NET, sure, but also PHP, Python, Java (Tomcat or Jetty or your own container), and node.js. Getting these things to work together has been an interesting software issue. Apps can run side-by-side, but they can't really talk to each other in-process. (Mostly one just moves data between universes over JSON and HTTP when need-be.)
However, Tomasz Janczuk has been working on Edge.js (on Github) for a while now. I showed his work at jQuery Portland last year, but this week he's taking it to the next level. He is creating a wormhole between software universes.
Edge.js now lets you run node.js and .NET code in-process on Windows, Mac, and Linux.
The name is great. An edge connects two nodes, and Edge.js is that edge.
Here's a node app hello world node app calling .NET. Don't sweat that the .NET code is tunneled inside a comment, this is the Hello World proof of concept.
var edge = require('edge');
var helloWorld = edge.func(function () {/*
async (input) => {
return ".NET Welcomes " + input.ToString();
}
*/});
helloWorld('JavaScript', function (error, result) {
if (error) throw error;
console.log(result);
});
Perhaps you have a bunch of CPU intensive work or algorithms in C#, but you've also got a node.js app that needs the result of that work. Edge can help with that.
You can bring in a CS or CSX file into node like this:
var myCSharpCode = edge.func(require('path').join(__dirname, 'myCSharpCode.csx'));
You can bring code from a .NET DLL into a node.js compiled as well.
var clrMethod = edge.func({
assemblyFile: 'My.Edge.Samples.dll',
typeName: 'Samples.FooBar.MyType',
methodName: 'MyMethod'
});
It's not a hack, it's a clear way to marshal between CLR threads and the V8 (the node Javascript engine) thread. It's also interesting from a comp-sci perspective as the CLR can have many threads and V8 has the one.
Here's Tomasz's own words:
Edge.js provides an asynchronous, in-process mechanism for interoperability between Node.js and .NET.
You can use this mechanism to:
- access MS SQL from Node.js using ADO.NET more...
- use CLR multi-threading from Node.js for CPU intensive work more...
- write native extensions to Node.js in C# instead of C/C++
- intergate existing .NET components into Node.js applications
Read more about the background and motivations of the project here.
Now, you might ask yourself, what problem does Edge.js solve? The answer is in the Edge.js FAQ.
Go explore what you can do. Edge goes much further than just C# and Node. It works on Windows, OSX, and Ubuntu but you should just "npm install edge" as there's a node package available.
- How to: integrate C# code into Node.js code
- How to: specify additional CLR assembly references in C# code
- How to: marshal data between C# and Node.js
- How to: call Node.js from C#
- How to: export C# function to Node.js
- How to: script Python in a Node.js application
- How to: script PowerShell in a Node.js application
- How to: script F# in a Node.js application
- How to: script T-SQL in a Node.js application
- How to: support for other CLR languages
- How to leverage SQL Server with Node.js using Edge.js
Have fun! You have a lot more power and flexibility than you think. It's just a software problem.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Who, in commercial projects, is mixing unix and windows technologies? Some geeks to show others how cool they are, they managed to write another 'hello world' app?
Sorry guys, but honestly I do not buy it. Ok. It is nice of Scott to tell people such technology exists, but for me, a guy being part of programmers team, it is a nightmare sometimes, to find the needle in tons of lines of code used in a hundreds of flavours. I think the pressure of using new techniques is driving towards massive spaghetti code, while in most cases technology could be simple and effective.
OK. So you have node, which is capable of serving HTTP Requests with *just a few lines of code*. And now you can use edge to let that HTTP server also execute in-process C# code *with just a simple function call*
How is this complex? It's about as simple as it gets - the edge author has done all of the hard work for you already...and as he tweeted - now it's not "Node vs .NET", it's "Node AND .Net" :)
Perhaps we can't think of a specific practical use right off the top of our heads, but for example imagine someone who has a core library of business logic built in C# that drives an ASP.NET WEB API app, but now they want to switch away from IIS/ASP.NET and use Node (for whatever reason)....suddenly they don't have to rewrite their application core any more. Which is nice.
And if the Mono/.NET stack is handling the more intensive math, that negates one of the drawbacks of Node, doesn't it? That would be another benefit.
The only real drawback I see, if you're .NET > all, is that it lowers the barrier to entry for migrating off the .NET stack to the NodeJS one (or at least, outside of the intensive bit mentioned before). Microsoft has apparently taken a stance of caring less about the means to the end (the language/platform used) vs trying to lock down developers to the .NET stack as before (they do, however, support and enhance the stack, so I'm not trying to pull a 'Microsoft abandoning .NET' FUD statement here). No, this isn't a Microsoft project, but from what I've seen in the past couple years Microsoft would embrace this, not attempt to shut it down/condemn it/break it/whatever.
I think when younger developers (primarily) are more interested in developing things in a specific way that also deviates quite a bit from the traditional way of the MS stack, that Microsoft is doing things right. You want .NET? Cool, from end to end they'll support you there. You want to do PHP/NodeJS/etc.? They can help you there too. You want to do Java? Please keep it off the desktop (my personal request. Refuse to install that on a desktop again. Which has kind of gimped my ability to do Android development with Android Studio/Eclipse, but collateral damage exists), but from a server aspect they've got you covered there too.
Items like query/write to SQL Server
Read/Write XLS/XLSX files
Parse JSON without crashing all the time (using JSON.NET, instead of the garbage JSON parser inside V8)
Its allowed us to really leverage the best of both new tech being written in node.js as well as the powerful and very useful tech that is well developed and mature in .NET.
I am really sorry and I have a lot of respect for you, Scott, but why are you pushing stuff like that?
If you need to create a nodeJS-app with .NET-Features/Code, than first of all ask yourself what's the benefit. NodeJS becomes a big number, yes, but productive-wise it's far behind what you'll get from MVC/SignalR... Not to speak off the maintainability.
The second alternative would be to write a CLR-Module and inject it into your v8-instance. But don't write C# as comments in JS-files. This is really the stupidest thing I've seen in a long time and this comes from a person who had to review code from business engineers...
Again, as I said in the post, the C# in a JavaScript comment tunneling is not what you want to use. Use an assembly. That said, Angular JS puts directives in comments and no one says boo.
If you guys think I'm "pushing" bad solutions, I would respectfully ask you to read closer and consider the increasing number of true polyglot solutions in the real world. Most significant apps are hybrids.
To those saying "what's the point, meat man?" The point is to let people work in the tools they're familiar with, but with the smallest possible gap between integration -- can you go stand up a remote server to do all your .NET/MP work and call that from node? Yeah sure, but what if that's actually totally overkill? It's probably overkill for lots of users.
* Parse JSON without crashing all the time (using JSON.NET, instead of the garbage JSON parser inside V8)
This is a big claim to make about v8 and JSON. I assume you do know what you are doing for sure but it doesn't change my surprise. Have you written / spoken about it in more detail somewhere?
Although it is cool and this research project should be banged around and put out there for defense as it is.
I have yet to work with Edge seriously but it's the kind of technology that allows developers to pick their tools, so while it probably won't ever gain widespread utilisation still has plenty of usages. And from a CompSci point of view it's very interesting seeing all this work together.
Edge.js has had an OWIN adapter since we interviewed Thomas on Herding Code last year. It's pretty slick, lets you plug OWIN compatible objects into an Express.js pipeline.
This is fine advice if your node app is a batch process, but I'm not sure its such great advice if you're hosting a REST API or other web-visible functionality. I would expect potential CLR thread starvation issues to result in a high-scale environment, as described here:
http://blogs.msdn.com/b/pfxteam/archive/2010/02/08/9960003.aspx
(that link isn't node-specific, but I think the same general principle would apply to edge.js code sitting behind a node web api, for example)
We should be thankful that someone has given us the ability to mix the advantages of libuv and the NPM ecosystem AND the advantages of c#/f#.
This is awesome software. Even more awesome that it was accomplished so succinctly/strategically.
:-)
I seldom help out a friend who owns a rather large website that consists of dozens of servers that are mixed between Linux and Windows. As well as a mixture of Classic ASP, Node, ASP.NET, Mono.
I'm currently working on a little project of my own where my website is on Windows and all image processing is done on Linux.
So yes people do mix technologies.
"It would be cool if it could expose the node request to .NET as an IDictionary<string, object> with properties filled per the OWIN spec."
Check out 'connect-owin'that implement node.js connect middleware in .NET using OWIN http://bit.ly/1d6FP9d
Take a look at the samples http://bit.ly/199LLKw
https://github.com/approvals/Approvals.NodeJS/blob/master/lib/Reporters/visualstudioReporter.js#L10
Was the simplest thing I could come up with.
To get this to run on both platforms I use a custom node install script (specified in package.json) to only install edge on windows. But havring the option to leverage it on both platforms would be great.
We currently use node.js to "mock" to our service layer when running a suite of selenium tests from within MSTest. Node.js was perfect for this.
You might like to take a look at the Screencasts by Ross. If you are running Windows 8/8.1/8.1.1 with Hyper-V enabled, you can install vagrant and configure chef (without installing virtual box et el.).
Once configured, all you need is to run this command in your work directory "vagrant up; vagrant ssh" via PowerShell; to switch the machine. Vagrant provides an easy command line capability to run VMs, while Chef keeps track of your recipes/screen-shots (like recorded macros in Excel/Firefox's Greese monkey) to let you dish out future VMs with everything pre-configured, pre-installed; by merely running a command.
I successfully executed couple of cross-platform projects using the aforementioned Vagrant workflow (well I used VirtualBox as Hyper-V wasn't supported back in the day)
HTH.
The issues with the V8/node JSON parser are well enough known that many many NPM modules have been created trying to solve the various shortcomings in various ways. Most seem to just wrap the JSON.parse inside a try/catch which solves the crashing but sadly doesn't do much to solve the ability to read the file.
The parser does a good enough job to handle computer generated json, but the moment you add any variations like simple trailing commas or comments, everything falls apart and you end up with failure instead of functionality.
Simply using almost any .net json parser and poof instead of frustrating error messages and unreadable files you get useful errors and, wow, actually readable files.
Frankly I find that most javascript engines are perfectly acceptable when everything is perfect, yet you add any variables to perfection and things get less reliable. Given that javascript is generally designed to fail off it makes sense but I do love programming in both C# and node.js so I make do with the tools I've got and make lemonade. Luckily we have edge.js to allow me and many others to quickly fix whatever shortcomings present in the quickest and least time consuming way possible.
I haven't published my quick hack for json yet but I have published a nice simple excel lib and a slightly more advanced SQL library than the basic (yet functional) example that comes with edge.
Github/camMCC/aps-sql and aps-excel
Also a good example on using typescript with edge as well as referencing dlls and using cs code in proper cs files.
More, I'd like to get a sequence of notification from the .net code, in a deferred-fashioned style like JQuery. More, it would be useful to get data in raw format and to send it on the fly as raw format (without providing field name for each object), and then "objectify" it on the client. Is it possible to achieve this with edge-sql?
Thanks in advance
So, the same group is providing a robust set of user level, AND system level regression tests, that will identify 85-90% of all the pending failures, right?
Keep the Windoze crap away from the software that actually works, without concern. Otherwise such drivel is handed the keys to open the door, and infect the working world
We have been working with Edge over the last week and have been quite happy with the results thus far. That said, we have run into an issue and I was hoping you could assist with shedding some light.
Using Edge from .net, we are spinning up a node instance so we can run in-process via windows service. Everything was working well and we were able to debug the .net assemblies. Today we added the 'cluster' module from node to take advantage of multi-core; however, Edge does not seem to like the implementation. Outside of Edge, all works well.
Do you have any advice on how we might go about debugging the issue or any tips you can pass over?
Thanks,
Mark
Comments are closed.