在JVM上运行Node.js
前言:本文章只是个人翻译自用,不喜欢者勿喷
最近在研究android与js交互
奈何本人能力有限,又是英语渣渣,特用机译方便理解
单一供应商锁定的日子已经一去不复返了,在整个组织中使用一种技术堆栈。即使是小型组织和业余爱好者,也会在一个项目中发现自己在混合技术。多年以来,Java一直统治着服务器。今天,Node.js无处不在。
但是,即使Node.js的兴起和JavaScript的普及,Java仍在继续发光。此外,很少有组织负担得起将整个平台从JVM迁移到Node.js的费用。这意味着组织必须继续使用其当前的技术堆栈,或者使用网络API运行多个堆栈进行通信。
另一个选择是在单个进程中运行Node.js和JVM,J2V8 最终使这成为可能。
J2V8是Java的一组V8绑定。J2V8将V8捆绑为动态库,并通过Java本机接口(JNI)为引擎提供了Java API。使用J2V8,您可以以类似于使用Rhino或Nashorn的方式使用V8执行JavaScript 。
J2V8最初是为了将高性能JavaScript 引入跨平台移动框架Tabris.js而开发的。
在过去的几个月中,我设法将Node.js构建为动态库,并为其提供了Java API。现在,您可以直接从Java执行Node脚本。与尝试使用其他JavaScript引擎实现Node.js的其他方法不同,这是真正的Node.js — 错误换功能,功能换功能。 Node.js与JVM在同一进程中运行,并且所有通信都是通过JNI同步完成的。
结合节点和JVM
J2V8提供了一个API,用于执行Node.js脚本,注册Java回调,调用JavaScript函数, 需要 NPM模块以及运行Node.js消息循环。Node.js核心模块也已被编译。
在JVM上运行Node.js,为希望开始使用Node.js的拥有大型Java堆栈的任何人提供了一条轻松的迁移路径。例如,您可以运行Node.js服务器(例如Express.js)并调用现有的Java方法来处理某些请求。
static String NODE_SCRIPT = "var http = require('http');\n"
+ ""
+ "var server = http.createServer(function (request, response) {\n"
+ " response.writeHead(200, {'Content-Type': 'text/plain'});\n"
+ " response.end(someJavaMethod());\n"
+ "});\n"
+ ""
+ "server.listen(8000);\n"
+ "console.log('Server running at https://127.0.0.1:8000/');";
public static void main(String[] args) throws IOException {
final NodeJS nodeJS = NodeJS.createNodeJS();
JavaCallback callback = new JavaCallback() {
public Object invoke(V8Object receiver, V8Array parameters) {
return "Hello, JavaWorld!";
}
};
nodeJS.getRuntime().registerJavaMethod(callback, "someJavaMethod");
File nodeScript = createTemporaryScriptFile(NODE_SCRIPT, "example");
nodeJS.exec(nodeScript);
while(nodeJS.isRunning()) {
nodeJS.handleMessage();
}
nodeJS.release();
}
NPM
除了从Node.js调用现有的Java方法之外,J2V8还提供了直接从Java调用JavaScript函数(以及扩展为NPM模块)的功能。通过这种集成,Java用户现在可以直接在JVM上开始使用NPM模块。例如,您可以使用Java 的jimp图像处理库。
public static void main(String[] args) {
final NodeJS nodeJS = NodeJS.createNodeJS();
final V8Object jimp = nodeJS.require(new File("path_to_jimp_module"));
V8Function callback = new V8Function(nodeJS.getRuntime(), new JavaCallback() {
public Object invoke(V8Object receiver, V8Array parameters) {
final V8Object image = parameters.getObject(1);
executeJSFunction(image, "posterize", 7);
executeJSFunction(image, "greyscale");
executeJSFunction(image, "write", "path_to_output");
image.release();
return null;
}
});
executeJSFunction(jimp, "read", "path_to_image", callback);
while(nodeJS.isRunning()) {
nodeJS.handleMessage();
}
callback.release();
jimp.release();
nodeJS.release();
}