paddybyers / anode

Android framework for node.js applications
Other
584 stars 81 forks source link

Anode? Node on Android? Guidance welcome #31

Open yaronyg opened 9 years ago

yaronyg commented 9 years ago

As mentioned in #28 it is now reasonably easy to build Android for Node (my own flavor of instructions are at http://www.goland.org/nodejsonandroid/). Now, it's not all fun and games. There are still basic things I'm trying to figure out such as https://github.com/TooTallNate/node-gyp/issues/515. But it looks like you can get there from here.

The project I'm working on (http://www.thaliproject.org) wants to create a run time environment that uses HTML5 as the front end and node.js on the back end and runs on Android, iOS, Windows Desktop, Windows Runtime (read: store apps and phone) as well as Mac and Linux. Yes, this does smell a little bit like node-webkit but we explicitly don't want the HTML 5 front end and the Node.JS code to be tightly bound. We are very happy with a model in which HTML5 runs in a browser or web view and the Node.js code runs in a completely separate process/thread that has its own life cycle. We need this because in places like mobile we want the node.js program to hang out forever (only really feasible today with Android) receiving requests and handling them. In our case we are using node.js to house PouchDB and handle synching data in our peer to peer web.

Which, finally, brings me to anode. I'm trying to figure out how to think about anode. I think our needs are actually less ambitious than anode. We would be perfectly happy just starting up a node.js process and letting it go. If the HTML 5 front end needs to talk to the node.js process then we are happy to do that over a localhost http connection. We even have a simple plan to use shared secrets to secure the connection so other apps on the same device can't sneak in.

Given our goals is anode what we should be looking at? Or would we be better off just wrapping up node on Android with a nice little spawn event inside of a Java wrapper and calling it a day? [1]

[1] And yes, I realize it won't be that easy. We'll need to handle life cycle events and surface them in node so it can gracefully shut itself off or know when there is no network connectivity. Our thinking is to expose these as standard events in node that would look the same on all of our platforms.

sequoiar commented 9 years ago

I did rewrite node.js in pure Java for Android http://instantwebp2p.github.io/node-android

yaronyg commented 9 years ago

@sequoiar - The goal is to have the 'same' environment on all our target platforms. So our ideal happy land is having main line Node everywhere. That's what's exciting about node's work on Android. It's just node. Not like node. Not sorta node. Just, node. This means that as node changes we don't have to run after it trying to update our code or figuring out how to be bug for bug compatible. It also means that we have a good shot of having node add-ons working as well. So we really just want to use node as is if we can. Make sense?

sequoiar commented 9 years ago

@yaronyg I did think run overall node.js env/modules on Android. But, I am frustrated that's complex adapt node.js native module to Android. node-android just is start point, like 0.2.x of node.js 4 years ago. And, in meantime node.js module has apple to apple Java implementation. so, I decided rewrite node.js in pure java and leverage what Android framework have.

paddybyers commented 9 years ago

Have you looked at Webinos (https://github.com/webinos) ?

This does have a lot in common with what you're trying to do - an HTML5 application environment, with javascript APIs implemented over JSON-RPC (over a socket or websocket, not http) to a separate node process. This runs on multiple platforms (windows, linux, android, etc). It uses anode for the Android implementation (and part-funded the work).

We had an implementation of the JSON-RPC between the webview and node process via Messenger, which means that it can have a permission associated with it - so long as the webview app and the node app have the same signer, then the channel would be secure. We eventually had to drop this approach when we moved from a webkit webview to a chromium one (related to the loss of content:// support at the time) but still that approach to securing the channel would work (assuming you are working with your own webview app and not intending to support arbitrary webview apps/browsers).

Even if this is architecturally not identical to what you want I'm sure there is a lot you could reuse there.

Your idea about the longevity of the node process is the same - it outlives any single application instance (and in the case of Webinos it means the APIs can be served to remote clients without any locally-running HTML app). The reason we chose the anode architecture was so that the node part would be able to call the java APIs in-process; it's not to allow node to run the process of the HTML app, but so that node can be loaded in a process forked from Zygote. That means it needs to be a library, and that in turn meant that we wanted to ensure that the library could be loaded, and node started and stopped, from time to time - ie to support multiple node instances serially even if not concurrently.

Unfortunately it's hard to recommend anode at the moment because the node port is just too old to be usable (it was around 0.6.2 that I stopped rebasing) - so quite a bit of work is needed to bring it up to the latest version. The java bridge part will also need rework because of the V8 API changes that happened in node 0.11.

yaronyg commented 9 years ago

@sequoiar Makes sense but I also have to find a path to iOS and Win RT. So Java isn't a good choice for me. Believe me, I feel this pain directly. I spent the last 8 months or so writing my project (http://www.thaliproject.org) in Java and now have to re-write in Javascript for the same reason.

@paddybyers I hadn't seen webinos but thanks for pointing them out. I wrote http://www.goland.org/html6packagedapps/ to explain what it is I'm trying to do and included webinos. I'm not super happy with their approach but our goals are so congruent that we must talk. On Android what I was planning on doing was creating a service, having it spawn a thread and then have the thread make a shell call to start NPM and run our service. All further communication would happen over a localhost HTTP connection. Because it's localhost we don't have to worry about interception or data leakage. But we do have to worry about impersonation and port hijacking attempts by other local apps. To prevent those attacks we would need to use a secret based challenge response security mechanism. I actually need to write a blog post explaining how that would work because there are so ugly attacks possible here. But that's the basic idea.