Node.net – Node.js implemented in Javascript on the .NET runtime
- Update:
This has gotten more attention after I posted this and I haven’t gotten around to doing another post. I started working on a v8 port of this after the initial JScript version just to see if it was feasible after I got some comments suggesting using v8 instead of JScript. There is currently a really rough version of the Tcp server done using v8 under v8\ along with my other hackings trying to figure out v8 embedding. I pushed the code up as soon as I had something working the other day, and c++ isn’t my first language so it is pretty rough. However I solved many of the tricky bits such as storing managed handles so that they can be accessed later from js.
I’ve been using Node.js recently and I’m loving it. I’ve dabbled in server-side Javascript on and off over the last two years or so with Rhino and later with writing my own hack servers using JScript on the .NET framework, and Node is hands-down the best way to run Javascript on the server to come along so far.
I got the idea last weekend that it should be possible to use the Microsoft JScript language to implement an event-driven server in .NET similar to Node.js. Before anyone gets too uppity about Node.net not being a full implementation of Node.js, let me say that this was a weekend hack that ended up working out, so I extended it just enough so that it should make sense to someone who is familiar with Node.js.
Goals
- Same theory of operation as Node.js (single threaded eventing front-end, non-blocking IO back-end)
- API compatibility with Node.js
- Written entirely in Javascript (JScript.NET)
- Runs on the .NET runtime
What is implemented
- Enough of the `http’ module to implement a basic server that handles post data and sends back response
- Enough of the `net’ module to implement a TCP server that echoes requests to stdout
- Enough of the `stream’ api to support the above
- require()
- sys.puts()
Limitations
- HTTP requests are cached by .NET even though the stream is read async. This was a limitation of using HttpListener in .NET. The TCP server is fully streaming however.
- Writes are implemented as blocking calls currently. I didn’t have time to implement write queues to enforce write ordering.
Download
A binary distribution is available here. Grab the source from here.
Usage
On Windows:
If you have the .NET 2.0 framework installed (likely if you are on a Windows box), just run the build script. If you’d rather build against a different framework version, you can alter the path to jsc.exe.
C:\> node.exe server.js
On Linux, under Mono:
C:\> mono node.exe server.js
In order to run under Mono, you’ll need Microsoft’s version of Microsoft.JScript.dll, which is included in the .NET framework. I can’t provide it here since it is not redistributable individually.
Examples
Running an HTTP server that prints post data to the console and replies with an `All finished’ message when the request completes:
var sys = require( 'sys' ), http = require( 'http' );
http.createServer( function( request, response ) {
request.addListener( 'data', function( data ) {
sys.puts( data );
});
request.addListener( 'end', function() {
response.write( '<html><body><p>All finished!<p></body></html>' );
response.end();
});
}).listen( 9981, 'localhost' );
To test it out, try something like this:
C:\>curl http://localhost:9981 -d "hello" <html><body><p>All finished!<p></body></html>
Running a TCP server that listens on port 9982 and writes data sent to the console:
var sys = require( 'sys' ), net = require( 'net' );
net.createServer( function( stream ) {
stream.addListener( 'data', function( data ) {
sys.puts( data );
});
}).listen( 9982, 'localhost' );
To test out the TCP server try sending it some data using telnet:
C:\>telnet localhost 9982
Although I’m aiming to expose everything as an API that is compatible with Node.js, you can access the .NET framework from within the Javascript that runs under Node.net.
For example, the TCP server shown above could have used Console.WriteLine() in order to write its output to the console:
var net = require( 'net' );
net.createServer( function( stream ) {
stream.addListener( 'data', function( data ) {
System.Console.WriteLine( data );
});
}).listen( 9982, 'localhost' );
The preceding samples are exactly the same as the code you would have written to accomplish the tasks in Node.js (with the exception of Console.WriteLine() of course ).
Building from source
Get the source from github here.
On Windows:
C:\> build.bat
On Linux
Mono’s mjs compiler doesn’t compile Node.net. Let me know if you get it to work.
Future work
Non-blocking writes is the biggest unimplemented piece of the architecture. After having gotten the locking semantics figured out for the main dispatch loop to avoid races (I think it is correct — if you are a threading guru I invite you to double-check my work), I didn’t feel like tackling writes. The current HTTP implementation isn’t streaming, and should be rewritten to use the `net’ module instead. This would entail writing an HTTP parser, which I wasn’t prepared to spend time doing. Also, most of the Node.js API remains unimplemented. I haven’t looked at the source code for Node.js much, but I’m wondering if some of its Javascript code could be ported to work with Node.net.
[...] Link: Node.net – Node.js implemented in Javascript on the .NET runtime … [...]
Node.net – Node.js implemented in Javascript on the .NET runtime … « 技術者派遣の技術日誌ブログ
May 8, 2010 at 11:56 am
Neat! What about actually using V8 for this?
kuroikaze85
May 14, 2010 at 9:10 am
Could you please provide a builded version?
Fedor Indutny
May 23, 2010 at 10:29 pm
@Fedor Indutny – there’s a link to a binary version in the post:
http://www.box.net/shared/bh905h17cp
Brian McKenna
May 23, 2010 at 11:59 pm
AFAIK JScript.NET is deprecated,did you try it with http://github.com/fholm/IronJS dlr implementation?
Best wishes.
Andrey Skvortsov
May 24, 2010 at 10:14 am
thanks for ur script
herupriadi
June 30, 2010 at 12:42 am
Interesting work,I like JScript.Net, too, but what about Managed JScript?
frank
September 15, 2010 at 6:59 pm
@frank Thanks! — Actually JScript.NET is the same thing as what you are referring to as Managed JScript I believe. If you look at the JScript version of Node.net (there are now 3 different implementations — IronJS, V8, and JScript) it is fully compiled to a .NET assembly using the JScript .NET compiler (jsc.exe). At least I think that is what you meant.
newcome
September 15, 2010 at 11:48 pm
You can also try to use Jint JS engine, i had used it successfully in a number of my projects.
Alexander Nikitin
December 8, 2010 at 8:55 am
You can also look at this project as it seems to be fairly active:
http://javascriptdotnet.codeplex.com/
Also, have you thought about getting this hosted on codeplex or github (the github link in your post is broken) so that you can get some help with this!? This would be a great tool to help with SSJS!!! Great work!
bbqchickenrobot
January 13, 2011 at 5:06 pm
@bbqchickenrobot Thanks for checking this out. The github link worked for me, but the link again is https://github.com/dnewcome/Node.net There is a version there where I’m using V8 which looks similar to what they are doing with javascriptdotnet. I started to move away from that toward using IronJS though. Thanks for the pointer to javascriptdotnet.
newcome
January 13, 2011 at 5:41 pm
[...] with Mono …Cannot add comment at this time. Maga D Zandaqo, Web Developer http://newcome.wordpress.com/201…https://github.com/dnewcome/Node…Important! Node.js is developed very fast and changed much since [...]
Is it there already an implementation of node.js for .NET/Mono? - Quora
January 14, 2011 at 8:59 am
Hello! nice blog!
propecia
January 23, 2011 at 9:14 am
[...] the past year or so I have been working on-and-off on a project called Node.NET in which I have experimented with embedding several different Javascript implementations within the [...]
Embedding IronJS – Part II « Dan Newcome, blog
March 13, 2011 at 11:53 am
Great achievement! I’m looking forward to seeing how this project evolves…
Ege
April 13, 2011 at 1:10 am
http://msdn.microsoft.com/en-us/netframework/aa497288#System.Net
un-lucky T^T
my jsc post this pages
hslee
May 25, 2011 at 8:49 pm
peace sign tattoo pictures,
Uhiewosn
July 4, 2011 at 5:07 am
I found this interesting because I have been playing with NodeJS on Windows and I ran into some behaviour which I just do not care for in the fs.Watch (directory watch) code. Node throws a whole bunch of extraneous “events” within fs.Watch. E.g., a simple file-save (update) throws two change events even if the file is tiny, whereas using DotNet FileSystemWatcher will limit to one event (on small files). I was just seeing what you had going here if it could be useful to me.
Houston SQL Server Developer
December 13, 2011 at 12:04 pm
@houston -
I never got around to implementing very much of the API, fs.* included. It’s something I’ll look into if/when I get back into this project again. Thanks for pointing this out.
newcome
December 13, 2011 at 3:26 pm
Brilliant idea and implementation! Nice work!
DAC
December 21, 2011 at 8:10 pm
Hello! bddggkd interesting bddggkd site!
dbgedkb
February 16, 2012 at 9:11 am