ASP.NET 5 Node Services
At the MVP Global Summit, Steven Sanderson (@stevensanderson) presented a Microsoft project he was working on: Node Services. In a nutshell, this is an integration of ASP.NET 5 and Node.js, it makes it possible to call a Node.js function from ASP.NET. One of its possible usages is to use Node.js to compile AngularJS directives or ReactJS JSX files, and for that reason, there are two modules built on top of Node Services just for that purpose (code available at GitHub and NuGet, here and here).
Disclaimer: this is still in early stage, and is likely to change!
So, after you install the NuGet package using the now familiar syntax:
You need to register the Node Services it in Startup.cs’s ConfigureServices method:
var app = services.Single(x => x.ServiceType == typeof (IApplicationEnvironment)).ImplementationInstance as IApplicationEnvironment;
services.AddSingleton<INodeServices>(new Func<IServiceProvider, INodeServices>(sp => Configuration.CreateNodeServices(NodeHostingModel.Http, app.ApplicationBasePath)));
Now, there are two ways by which ASP.NET can communicate with the Node.js host:
- HTTP (NodeHostingModel.Http): a local service is started which waits for JSON requests and routes them to Node.js;
- Interprocess communication (NodeHostingModel.InputOutputStream): a direct stream with the Node.js hosting process; should be much faster than the HTTP version.
Creating a Node.js module is easy; let’s add a .JS file to the project:
module.exports = function (cb, a, b)
{
a = parseInt(a);
b = parseInt(b);
return cb(null, (a + b).toString());
};
For simplicity’s sake, we are doing a very simple operation: just adding two numbers, but in a real-life scenario you can require any other Node.js modules and do any arbitrarily complex operations. You need to be aware of a couple of things:
- The first parameter to the exported function must be a callback function; this will be used for returning the result;
- Each parameter must either be a string or a JSON object;
- The result – second parameter to the callback function – also needs to be a string or JSON.
And how do you call this? You just need a reference to the registered instance of INodeService, and on it you call a module asynchronously, passing it some parameters:
var node = this.Resolver.GetService(typeof(INodeServices)) as INodeServices;
var result = await node.Invoke<string>("sum.js", "1", "2"); //"3"
You can also specify the module and function name explicitly, if you export it from the .JS file (not in this example):
var result = await node.InvokeExport<string>("sum.js", "sum", "1", "2");
Happy Noding!