LiquidPlayer / LiquidCore

Node.js virtual machine for Android and iOS
MIT License
1.01k stars 127 forks source link

Unable to find any proper examples. Which can help me to integrate a real time javascript project with Android (using Liquidcore ) . Can any one please help me in this? #90

Closed A-P-Singh closed 5 years ago

ericwlange commented 5 years ago

Can you be more specific? What are you trying to do?

A-P-Singh commented 5 years ago

I want an example project. which can gave me some basic understanding on how to integrate javascript code with Android using LiquidCore framework. I found one example but that is not sufficient for me-https://github.com/LiquidPlayer/Examples

Can you give me some others example code with javascript and Android ? If possible use some npm module in javascript and then integarte that with Android code (using liquid core)

conclusion: I need some examples code.

ericwlange commented 5 years ago

Have you followed the tutorial? It should give you a pretty good idea how to get set up.

Yes, you can npm install modules you want to use. The bundler will bundle all the modules together into a single file.

Without knowing exactly what you are trying to do, it is very difficult to point you to an example or to write one for you. LiquidCore can do quite a lot.

Please walk through the tutorial and let me know if it doesn't satisfy your needs, and if not, specifically why. I can't improve examples if people don't tell me what's wrong with them.

A-P-Singh commented 5 years ago

I Saw that tutorial in beginning . But its not sufficient :( I am tring to call a API using npm request .

Usecase: I want to call any API in Javascript and that that JSON I will send to android (liquidcode).

var request = require('request'); var postApi1 = { MethodAPIJson: function (‘url’, cb) { var options = { method: 'POST', url: url, headers: { ‘hearder1’: ’some string’, json: true };

        request(options, function (error, response, body) {
            if (error){
                cb(null,error)
            } else{
                cb(null,body)
            }
          });
    }
};
module.exports = postApi1;

Now can you give me some proper examples (links or code)? How to get this response body in liquidcore or in android?

ericwlange commented 5 years ago
npm i -g liquidcore-cli
liquidcore init request_example
cd request_example && npm install

Create postApi1.js:

var request = require('request');
var postApi1 = {
        MethodAPIJson: function (‘url’, cb) {
            var options = {
                method: 'POST',
                url: url,
                headers: {
                ‘hearder1’: ’some string’,
                json: true 
            };

            request(options, function (error, response, body) {
                if (error){
                    cb(null,error)
                } else{
                    cb(null,body)
                }
              });
        }
    };
    module.exports = postApi1;

(I'm not going to debug this module for you, but I can see some errors)

Edit index.js:

const postApi1 = require('./postApi1')

setInterval(()=>{}, 1000)

LiquidCore.on( 'request', (url) => {
    postApi1.MethodAPIJson(url, (body,error) => {
        LiquidCore.emit('response', { body: body, error: error })
    })
})

LiquidCore.emit( 'ready' )

Once you receive the ready event in Java, you can make requests by calling:

service.emitString("request", myURLString);

Make sure you register for the response event:

final EventListener responseListener = new EventListener() {
    @Override
    public void onEvent(MicroService service, String event, final JSONObject payload) {
        // event should be "reponse"
        // payload.getString("error") will contain the error, or null
        // payload.getString("response") will be the response body
    }
};
service.addEventListener("response", responseListener);        
A-P-Singh commented 5 years ago

Thanks for your support. What should I write address info in MainActivity.java ,when I run application in my local machine? i.e // IMPORTANT: Replace this with YOUR server's address or name private final String serverAddr = "192.168.2.152";

What should I write here for running locally?

ericwlange commented 5 years ago

The example code may be slightly out of date. I'll have to fix that. But the tutorial code is up-to-date.

If you want to run a local dev server, use the code as described in the tutorial:

URI uri = MicroService.DevServer();
MicroService service = new MicroService(MainActivity.this, uri, startListener);
service.start();

When you run npm run server locally, this will connect to that server if you are using the emulator. This is helpful for development and debugging because you can hot reload while you are developing your javascript.

Once it is stable, if you want to store code as an asset or raw file on the device, you would run:

npm run bundler -- --platform=android

This will generate a file called liquid.bundle which is a single file with all of your js code bundled into it.

You can either copy it (and rename it to liquid.bundle.js) to /res/raw and then the URI would be android.resource://<your package name>/raw/liquid.bundle, or to your assets folder and use the URI file:///android_asset/liquid.bundle (without renaming).

ericwlange commented 5 years ago

The example code is unfortunately only updated to version 0.5.1. It still works, of course, but the tutorial is using 0.6.0 which includes the dev server. Prior to 0.6.0, MicroService.DevServer() did not exist. I highly recommend using 0.6.0.

A-P-Singh commented 5 years ago

I have already done the above changes. what ever you are suggesting. But I am getting below error in server console and 500 error code in java . Java console ERROR:

2019-03-09 14:24:35.023 21094-21117/org.liquidplayer.examples.helloworld D/NetworkSecurityConfig: No Network Security Config specified, using platform default 2019-03-09 14:24:35.024 21094-21117/org.liquidplayer.examples.helloworld D/MicroService: User-Agent : LiquidCore/0.6.0 (Android; API 27) 2019-03-09 14:24:35.125 21094-21117/org.liquidplayer.examples.helloworld E/FileNotFound: responseCode = 500 2019-03-09 14:24:35.125 21094-21117/org.liquidplayer.examples.helloworld W/System.err: java.io.FileNotFoundException 2019-03-09 14:24:35.125 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.service.MicroService.fetchService(MicroService.java:649) 2019-03-09 14:24:35.125 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.service.MicroService.onProcessStart(MicroService.java:778) 2019-03-09 14:24:35.125 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.node.Process.eventOnStart(Process.java:217) 2019-03-09 14:24:35.126 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.node.Process.access$1000(Process.java:24) 2019-03-09 14:24:35.126 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.node.Process$3.__nodedroid_onLoad(Process.java:350) 2019-03-09 14:24:35.126 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at java.lang.reflect.Method.invoke(Native Method) 2019-03-09 14:24:35.126 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.javascript.JSFunction.function(JSFunction.java:517) 2019-03-09 14:24:35.126 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.javascript.JSFunction.functionCallback(JSFunction.java:467) 2019-03-09 14:24:35.126 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.node.Process.runInThread(Native Method) 2019-03-09 14:24:35.127 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.node.Process.access$100(Process.java:24) 2019-03-09 14:24:35.127 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at org.liquidplayer.node.Process$1.run(Process.java:111) 2019-03-09 14:24:35.127 21094-21117/org.liquidplayer.examples.helloworld W/System.err: at java.lang.Thread.run(Thread.java:764) 2019-03-09 14:24:35.142 21094-21117/org.liquidplayer.examples.helloworld I/sessionWatchdog: deleting session /data/user/0/org.liquidplayer.examples.helloworld/cache/org.liquidplayer.node/sessions/8501aacc-0d07-4c2b-8ca1-9428fb61cb57

Server Console Error: Metro Bundler ready.

Loading dependency graph, done. error: bundling failed: Error: Unable to resolve module crypto from /Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/request/lib/helpers.js: Module crypto does not exist in the Haste module map

This might be related to https://github.com/facebook/react-native/issues/4968 To resolve try the following:

  1. Clear watchman watches: watchman watch-del-all.
  2. Delete the node_modules folder: rm -rf node_modules && npm install.
  3. Reset Metro Bundler cache: rm -rf /tmp/metro-bundler-cache-* or npm start -- --reset-cache. 4. Remove haste cache: rm -rf /tmp/haste-map-react-native-packager-*. at ModuleResolver.resolveDependency (/Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:167:1306) at ResolutionRequest.resolveDependency (/Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:80:16) at DependencyGraph.resolveDependency (/Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/node-haste/DependencyGraph.js:237:485) at Object.resolve (/Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/lib/transformHelpers.js:116:25) at dependencies.map.result (/Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/DeltaBundler/traverseDependencies.js:298:29) at Array.map () at resolveDependencies (/Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/DeltaBundler/traverseDependencies.js:294:16) at /Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/DeltaBundler/traverseDependencies.js:159:33 at Generator.next () at step (/Users/ajay.a.prakash.singh/Documents/rough-work/Examples-master/HelloWorld/helloworld/node_modules/react-native/node_modules/metro/src/DeltaBundler/traverseDependencies.js:239:307) BUNDLE [android, dev] ./liquid.js ░░░░░░░░░░░░░░░░ 0.0% (0/1), failed.
ericwlange commented 5 years ago

In your AndroidManifest.xml:

    <application
        android:usesCleartextTraffic="true">
    </application>
ericwlange commented 5 years ago

Sorry, I responded too quickly. This is a problem with the bundling.

Which version of liquidcore-cli is installed?

A-P-Singh commented 5 years ago

{ "name": "helloworld", "version": "0.0.1", "private": true, "scripts": { "start": "node node_modules/liquidcore-cli/cli.js", "server": "node node_modules/liquidcore-cli/cli.js server", "bundler": "node node_modules/liquidcore-cli/cli.js bundle" }, "dependencies": { "liquidcore-cli": "^0.1.2", "react-native": "0.56.0", "request": "^2.88.0", "request-promise-native": "^1.0.5" } }

ericwlange commented 5 years ago

Please update to the latest liquidcore-cli. It should be 0.1.5, I think.

ericwlange commented 5 years ago
npm remove -g liquidcore-cli
npm install -g liquidcore-cli

And also update it locally:

npm install liquidcore-cli

It should read "liquidcore-cli": "^0.1.5".

A-P-Singh commented 5 years ago

Thank you so much for your support. Now all the above issue if fixed :)

But If I use var request = require('request'); npm module for calling a third party API then I am getting below error: 2019-03-09 18:05:29.009 27357-27388/org.liquidplayer.examples.helloworld E/libc: Access denied finding property "net.dns1" 2019-03-09 18:05:29.004 27357-27357/org.liquidplayer.examples.helloworld W/nodejs: type=1400 audit(0.0:603): avc: denied { read } for name="u:object_r:net_dns_prop:s0" dev="tmpfs" ino=7512 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:net_dns_prop:s0 tclass=file permissive=0 2019-03-09 18:05:29.126 27357-27388/org.liquidplayer.examples.helloworld E/JSEXCEPTION: Unhandled exception: TypeError: The super constructor to "inherits" must have a prototype 2019-03-09 18:05:29.126 27357-27388/org.liquidplayer.examples.helloworld E/JSEXCEPTION: liquid.bundle.js:894 throw e; ^

TypeError: The super constructor to "inherits" must have a prototype
    at Object.inherits (util.js:975:11)
    at liquid.bundle.js:2463:8
    at loadModuleImplementation (liquid.bundle.js:308:7)
    at guardedLoadModule (liquid.bundle.js:236:14)
    at metroRequire (liquid.bundle.js:217:119)
    at liquid.bundle.js:2146:20
    at loadModuleImplementation (liquid.bundle.js:308:7)
    at guardedLoadModule (liquid.bundle.js:236:14)
    at metroRequire (liquid.bundle.js:217:119)
    at liquid.bundle.js:1733:21

Can't we use npm request modiue in Liquidcode framework for calling any API? If not then how can I call Any API?

ericwlange commented 5 years ago

Can you send me your liquid.bundle (npm run bundler -- --platform=android)? I would need to follow the stack trace.

It seems like there may be a circular dependency. The metro bundler really does not handle circular dependencies well. I already modified it once to fix some of these issues. This may be another edge case.

ericwlange commented 5 years ago

This is not a good long term solution, but ...

Edit node_modules/sshpk/lib/private-key.js. Line 43 should say:

util.inherits(PrivateKey, Key);

Replace it with:

//util.inherits(PrivateKey, Key);
PrivateKey.prototype = {}

This should solve that particular problem. However, it is not a great solution because PrivateKey is supposed to inherit from Key, but this will break that inheritance. If you are not running code (ssh) that depends on it, then you won't see any problems, but if at some point you run into something that expects this to be the case, you may get an error.

The problem is that the sshpk module is using cyclic dependencies. You can see that private-key.js has the line:

var Key = require('./key');

while key.js contains:

var PrivateKey = require('./private-key');

which means that each module is including the other. If you are running directly out of node_modules/, like you would do with regular nodejs, this will work ok because it does the module loading dynamically. But because we are bundling into a single file, it does all the requires up front during bundling, rather than at runtime. Normally this is still ok, because I've modified the bundler to use a Proxy to the real object when it is cyclically loaded, but in some cases this isn't enough.

I don't have a better solution for this at the moment. I have some ideas how to solve it long term, but for now, cyclic modules may cause problems and you will have to hack it, like this.

ericwlange commented 5 years ago

I take it back. I found a clean solution.

Upgrade to liquidcore-cli version 0.4.6 by changing your package.json file and running npm install.

It should fix the problem properly.

A-P-Singh commented 5 years ago

Thank you So much @ericwlange :) All the above issues are fixed. Suggestions: If you and your team can create some example of some common scenarios and upload that to some where in git then it will be very help full for developers.

Thanks Again :)

ericwlange commented 5 years ago

Glad I could be of help.

Unfortunately, I have no "team". It is just me, developing this thing on nights and weekends. For free. I would like to write more documentation, but it would come at the expense of development. I'm hoping some of the developers who use it could write some more blog posts like this one.

A-P-Singh commented 5 years ago

I take it back. I found a clean solution.

Upgrade to liquidcore-cli version 0.4.6 by changing your package.json file and running npm install.

It should fix the problem properly. FYI, I changes the liquidcore-cli to 0.4.6. But still that issue is not fixed .

2019-03-12 10:48:36.127 5317-5351/org.liquidplayer.examples.helloworld E/JSEXCEPTION: Unhandled exception: TypeError: The super constructor to "inherits" must have a prototype 2019-03-12 10:48:36.127 5317-5351/org.liquidplayer.examples.helloworld E/JSEXCEPTION: liquid.bundle.js:894 throw e; ^

TypeError: The super constructor to "inherits" must have a prototype
    at Object.inherits (util.js:975:11)
    at liquid.bundle.js:7762:8
    at loadModuleImplementation (liquid.bundle.js:308:7)
    at guardedLoadModule (liquid.bundle.js:236:14)
    at metroRequire (liquid.bundle.js:217:119)
    at liquid.bundle.js:7445:20
    at loadModuleImplementation (liquid.bundle.js:308:7)
    at guardedLoadModule (liquid.bundle.js:236:14)
    at metroRequire (liquid.bundle.js:217:119)
    at liquid.bundle.js:7032:21
ericwlange commented 5 years ago

Try:

npm run server -- --reset-cache

and see if that fixes the problem?

praveenkg85 commented 5 years ago

@ericwlange, locally generated (through npm run bundler) liquid.bundle file works fine with Android. For iOS, it works fine only with Carthage but throws error with Cocoa Pod (invalid character '\uffff' at line...). Although, it works fine with running the dev server, but due to some limitation, we have to run npm bundle for liquid core and generate liquid.bundle file. Node:- "liquidcore-cli": "^0.4.7" iOS:- liquidcore 0.6.0

Can you please help me resolve this error?