Execute NPM module through cordova - javascript

I created an app using cordova and everything is fine, expect I need to use a node module which doesn't have a client-side equivalent because I'm dealing with file write streams etc. I have found Cordova hooks to be my best shot so far, where I create an app_run hook to execute a node file that runs a socket server to listen for events from the client side.
I know, a very longwinded solution, but seems logically correct to me, the issue is that when I do create the server, building the app through Visual Studio 2017, the app launches on my android phone, but VS hangs on the "deploy" stage. I guess that it has to do with the event chain, so I created an asynchronous script like this:
(async function () {
const server = require('http').createServer()
const io = require('socket.io')(server)
io.on('connection', function (socket) {
console.log('heyo')
socket.emit('hello world', 'hi')
})
server.listen(3000, function (err) {
if (err) throw err
console.log('listening on port 3000')
})
})();
but this doesn't seem to work either, somehow VS hangs on "deploy". If anyone can possibly guide me in the right direction, that would be highly appreciated.
PS: I know the title is off, but every time I use StackOverflow to get help with a particular attempt, I'm told to do it another way, so I'll leave it open.

If the goal is to use socket.io in your cordova app, there IS a JS client for the web that you need to use and you don't need to use npm for that, just add a link to your client js file in your index file. (should be in a "client" folder when you init socket.io via npm).
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('http://localhost');
</script>
https://socket.io/docs/client-api/

Related

using MQTT.js (node package) in electron to update dom

I am new to electron and node.js working on mqtt to update the DOM. I receive message on mqtt to my main.js onmessage function and my main.js is
const { app, BrowserWindow } = require('electron')
var mqtt = require('mqtt')
var client = mqtt.connect("mqtt://localhost")
client.on("connect", function(){
client.subscribe("testtopic")
})
client.on("message", function(topic, message, packet){
document.getElementById("someId").innerHTML = message
})
function createWindow () {
const win = new BrowserWindow({webPreferences:{nodeIntegration: true}})
win.loadFile('index.html')
win.maximize()
}
app.whenReady().then(() => {
createWindow()
})
And I would like to update the element which is available in index.html from my onmessage callback. I cannot access it shows error document is not defined.
How to achieve this or can I import mqtt directly in my index.html script ?
in that case why use node mqtt instead I can use paho mqtt.
Please advice on this.
That code is running in the "backend" not in the browser, so will have no access to the DOM.
If you want update the DOM in response to MQTT messages you have a couple of choices.
Implement a MQTT over WebSockets in the index.html file that will subscribe to the broker directly in the page and will have direct access to the DOM. You can use either the MQTT.js or the Paho client in the page, but you will need a broker that has specifically been configured to support MQTT over WebSockets.
Look at setting up some direct connection between the backend code and the loaded page, the following question might help with some pointers: How to access DOM elements in electron?

Can't connect to my WebSocket from within my Angular2 app

Hej there.
I have a app using Node.js/Electron/Angular2 (TypeScript). Using socket.io I created a WebSocket. Everything works fine, as long as I'm not inside my Angular2 app.
I tried the whole day to get this running, without luck. I downloaded a working tutorial, but can't find the missing link. Drives me crazy!
This is my electron.js starting the app, creating the websocket server side
This is my index.html with working websocket, but as native JavaScript code
This is my root component of Angular2 trying to get the websocket running
The error - wich does not stop the compilation - I get, is root.component.ts(14,17): error TS2304: Cannot find name 'io'..
How can I get rid of that error? Or better: What's the best practice for this websocket communication inside Angular2?
Thanks in advance.
Now I solved this issue this way:
Installed socket.io-client typings $ tsd install socket.io-client and
added a typings reference to my main.ts file ///<reference path="../../typings/socket.io-client/socket.io-client.d.ts"/>.
Installed socket.io-client Node.js module $ npm install --save socket.io-client and
added this module to my index.html <script src="../node_modules/socket.io-client/socket.io.js"></script>
Now I can simply work with the socket inside any Angular2 component, without adding any extra lines.
socket = null;
constructor() {
this.socket = io('http://localhost:8181');
this.socket.on('news', function (data) {
console.log(data);
});
}
And for reference, this is my server socket code inside my main Electron .js file:
var server = require('http').createServer(function(req, res) {})
socket = require('socket.io')(server, {});
server.listen(8181);
socket.on('connection', function(socket) {
socket.emit('news', {hello: 'world'});
socket.on('my other event', function(data) {
console.log(data);
});
});
Hope this helps anyone later. Thank to Thierry Templier and dvlsg for the help.
I would note that if you're using electron that you shouldn't really consider electron.js to be server side. It's more of a client launcher / bootstrap, and must be running on each client. You'd have to have a separate node application (and I would strongly suggest it, in the case of socket.io) to truly make your code server side.
As for your question, you could try adding import io from 'socket.io-client' or var io = require('socket.io-client') in your root component (after you npm install socket.io-client, if necessary).
You need to install the socket.io typings (see this link: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/socket.io/socket.io.d.ts) using the command:
$ tsd install socket.io
Then you need import it:
import * as io from 'socket.io';

Automate UI testing with Javascript, node - starting & stopping a web server

I'm currently investiagating automated UI testing using JavaScript on windows with node.js and phantom.js and unsurprisingly I've found many frameworks that can help in this regard (casper.js, Buster.js, etc).
The one thing that seems to be missing from the frameworks I have looked at so far is stopping and starting a web server to server the web pages so that testing framework can perform its testing. One exception is WebDriver.js which uses the Selenium standalone server but this relies on a server written Java and at the moment I'd prefer to find a node based solution if at all possible.
From the node perscpective I've looked at Connect.js and also Http-Server (which I particularly like) but the issue is starting and stopping these from a JavaScript test.
I've attempted to create a casper.js test that would interact with a server, run the test and then stop the server but I can't get it to work, here's an example script
var childProcess = require('child_process').spawn('http-server', '/TestSite');
casper.test.begin("Load-page", 1, function suite(test){
casper.start('http://localhost:8080/',function(){
test.assertTitle("test page");
});
casper.run(function(){
test.done();
childProcess.kill();
});
});
I call this from the command line using the following command (casper is in my Path variable):
casperjs Load-page testFile.js
What I was hoping would happen is the http-server would start, casper would start the test and then after the test was run the http-server would be killed.
I've also tried similar with Connect:
var server= connect.createServer(connect.static('/TestSite')).listen(8080)
casper.test.begin("Load-page", 1, function suite(test){
casper.start('http://localhost:8080/',function(){
test.assertTitle("test page");
});
casper.run(function(){
test.done();
server.stop();
});
});
But again with no luck.
I can run the Casper sample tests which work and I've also got Node in my Path as well and can call the REPL from the command prompt.
The directory structure is:
Code
/TestSite
/node_modules
and I run the tests from the Code folder.
Am I simply unable to do this or am I just not getting how it should work?
When you say "no luck" what do you mean?
The connect example looks mostly OK, and I'd prefer it over spawning a subprocess. Bear in mind that listen is potentially async so the server might not be available immediately though. The second param to listen is a callback that will be run once the server is listening - maybe try running the tests in that callback instead?
Pro Tip: Don't rely on port 8080 always being free on whatever machine you're running on - passing in 0 for the port will cause the server to start on a random port, you can then do server.address().port in the listen callback to get the port that was chosen
I managed to get it working using a combination of differebt scripts and using child_process spawn.
I created a script called startServer.js that would start the server using Connect:
var connect = require('connect');
var server= connect.createServer(connect.static('TestSite'));
server.listen(8081);
I created another script runTests.js that would call the server script via spawn and then call Casper, again via spawn, and run all the capser tests that are in a folder called tests relative to where the script is run from.
var child_process = require('child_process');
var stillRunning = true;
var server = child_process.spawn('node', ['createServer.js']);
var casper = child_process.spawn('casperjs', ['test tests']);
casper.stdout.on('data', function(data){
console.log(data.toString());
});
casper.stderr.on('data', function(data){
console.log('Error: ' + data);
});
casper.on('exit', function(code){
server.kill();
process.exit(0);
});
To use this at the command prompt navigate to the folder where the script is and then run node runTests.js and the server will be started and the tests run against the site

Why can't I run node.js & socket.io in a screen or with Forever?

I've got some annoying problem and that is I have trouble in running nodejs in a screen. Because as fast as I leave the screen and no sockets are connected the next whom is to connect will be faced by an error message until the screen is opened again. As soon as the screen is open with screen -R node (for example) it will start accepting connections again.
However notice that if the screen is closed (running in the background) and someone already has a socket open, it will continue to answer new connections.
When I try to start the application again, with the command node app I get the following message:
module.js:340
throw err;
^
Error: Cannot find module '(unreachable)/square_defense/app'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.runMain (module.js:492:10)
at process.startup.processNextTick.process._tickCallback (node.js:244:9)
Server side code:
var app = require('express')()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);
server.listen(3000);
app.get('/', function (req, res) {
console.log(__dirname);
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.on('user-message', function (data) {
console.log(data);
sendMessage.call(socket, data.message);
});
});
var sendMessage = function(message) {
this.emit('server-message', {message: message});
this.broadcast.emit('server-message', {message: message});
}
I have tried a lot of things like npm install app in directory .. from the app.js. Can't understand why it dont want to work. I really just want a server which I can use for testing purposes that do not crash.
EDIT: I think this has something to do with an encrypted home folder?
I think the unreachable folder is where the problem resides. Error: Cannot find module '(unreachable)/square_defense/app'. But I don't know why this is happening. Right now I am running the application with Forever and as soon as I have an ssh-session on it will work. But as soon as I exit the connection and reload the page. It will generate an error.
As you said, your home directory is encrypted, and according to the document from Ubuntu:
This directory is automatically mounted on login, and unmounted on logout.
So your guess is correct, this is exact what's causing the error. Running a detached screen session won't be considered by the OS as the user are still logged in*. The time all shell sessions of the user ends, the encrypted home directory got unmounted.
Solution: You can move your app to a directory other than $HOME, then I think either GNU Screen or forever will do the job without errors.†
* You can test this by your self: login, start a screen session, run something like vim, detach; use command w to see who is logged in and what they are doing
† I think if you write your own upstart scripts for this, it is still crucial that the app files are not placed in auto-encrypted home directory.
Since you already are on an Ubuntu box, i recommend using Upstart and monit as described in this post: http://howtonode.org/deploying-node-upstart-monit
The only thing i added into the mix was a frontend proxy-server (HAProxy in my case, but nginx works as well) in order to serve my application on port 80.
I deployed a socket.io/express app using this technology stack on Amazon EC2 myself about a month ago, with amazing results!
EDIT:
Here are some resources i collected over time concerning a proper production setup using node.js/nginx/monit/git:
http://cuppster.com/2011/05/12/diy-node-js-server-on-amazon-ec2/ (an awesome guide, helped me a lot!)
http://howtonode.org/deploying-node-upstart-monit
I really recommend the first one, you might have to skip some parts (like npm module installation or system setup), but the parts about nginx/git and supervisor are worth a read.

socket.io - ReferenceError: io is not defined

I am writing an application for Android 2.3.5 (that will also be compatible with iOS). I wish to transfer data from the app's HTML/Javascript to a Python program on a server (which uses the Twisted engine to retrieve the data).
I've tried many things and looked at various forums, answers, tutorials, and web pages--including most of them here--and can't find an answer. Here's the relevant Javascript I have in my index.html file:
<script src="socket-lib/socket.io.js"></script>
<script type="text/javascript" charset="utf-8">
function sendData() {
try {
var socket = io.connect('http://mywebsite.com:12345');
socket.on('connect', function(data) {
socket.send('Hello.');
socket.on('message', function (msg) {
socket.send('This is where I send data?');
});
});
}
catch(err) {
alert('ERROR: socket.io encountered a problem:\n\n' + err);
}
} // end of sendData
If you can't tell, I'm still pretty confused how this works; I can't even test anything. The error that keeps coming up is ReferenceError: io is not defined. Some sites used something like var io = require('socket.io');. But then it results in the same error: ReferenceError: require is not defined.
I put the socket-lib folder in assets/www, where any other Javascript source should go. This is also where the index.html file is. Many sites use <script src="/socket.io/socket.io.js"></script>, but this makes no sense to me. Many sites also imply the use of node.js, but I never see it anywhere.
How can I make this work?
Reply edits:
I tried it in Chrome, and it's giving me an Uncaught ReferenceError: require is not defined for the socket.io.js file. So I decide to source in require.js right before it. Then it gives the error Uncaught Error: Module name "socket.io-client" has not been loaded yet for context. Since I'm not using this, I care not. When I try the connection, though, it gives the same io is not defined error. When I define it as var io = require('socket.io'), the error is Error: Module name "socket.io" has not been loaded yet for context: _ http://requirejs.org/docs/errors.html#notloaded. I looked at the website, and it doesn't help me at all. When I try to put "require" as a function argument, another error occurs: TypeError: undefined is not a function.
I found the answer for anyone who gets immensely confused by the horrible lack of documentation of socket.io.
You cannot source /socket-lib/socket.io.js,
you must source http://yourwebsite.com:12345/socket.io/socket.io.js.
The server automatically does the rest for you.
I solved it myself by changing index.html to import the socket io client from bower, first i installed the bower component:
bower install socket.io-client
then i changed the reference in index.html to :
<script src="bower_components/socket.io-client/socket.io.js"></script>
Or file could be found at - lib/socket.io-client/dist/socket.io.js
I managed to blunder through this, and squandered about an hour, on something that turned out to be a very basic error.
When an function is not defined? Such as " Uncaught ReferenceError: io is not defined ". Does that not mean that the function is getting "used" before it is "created"?
In the part of my HTML file, that "calls" the javaScript files, it looked like this :
<script src='./js/playerChatter.js'></script> <!-- this one calls io -->
<script src="http://localhost:2019/socket.io/socket.io.js"></script><!-- This Creates io -->
and i changed it to this
<script src="http://localhost:2019/socket.io/socket.io.js"></script> <!-- This Creates io -->
<script src='./js/playerChatter.js'></script> <!-- this on calls io -->
So now the item "io", whether it is an object or function... Is actually getting created before it is getting used :D
Have FUN!
write server side code in socket.io.js file and try src="/socket.io/socket.io.js"
hope this will solve your problem
When getting socket.io to work with many other libraries using require.js I had same error, it turned out to be caused because of trying to load the socket.io.js file from the same /js folder than the rest of the other files.
Placing it in a separated folder, fixed it for me, you can see the code in this gist but all I changed for making it work, was this:
instead of:
socketio: 'socket.io',
Use:
socketio: '../socket.io/socket.io',
Not sure about the reason of this behavior, but I hope it helps you.
This looks like your browser cannot find the socket.io.js file. You could try opening the index.html on your computer with Firefox+Firebug or the Chrome Web Developer Tools and look at how the .js file is requested. On the other side, you could check the logs on the webserver serving the .js file whether there are any file not found errors.
The require function would be provided by e.g. RequireJS, but you would still need to configure the paths to your scripts correctly for it to work.
For me after debugging through all of the very helpful suggestions, it turned out to be simply that my node server had stopped. I had been running it manually in a terminal window during dev.
Make sure your node [yourservercode].js is running on the specified port! :-]
I use jspm.
Add this:
import 'btford/angular-socket-io/mock/socket-io';
In my case, using Unity WebGL with C# UnitySocketIO plugin, I need to add delay (1 sec) between Init and Connect, because the first method did not have time to add a new JS Socket object and code (listeners) to the page to work with it..
As mentioned in other answers, you have to use the complete URL.
<script src="http://127.0.0.1:5565/socket.io/socket.io.js "></script>
if it's giving you an error 404 please check whether io is properly instantiated on your server.js.If not please refer following to instantiate the io properly.
<script>
var socket = io();
</script>
In your server.js
const app = express();
const http = require('http'); //from express module
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
got to url /socket.io/socket.io.js and check if a js file is served or not if yes then instead of writing
var socket = io();
write
window.onload= function(){
var socket = io();
}

Categories