I'm trying to find the best way to send my users a real-time status update of a process that's running on my server - this process is broken up into five parts. Right now I'm just 'pulling' the status using an Ajax call every few seconds to a PHP file that connects to MySQL and reads the status, but as you can imagine, this is extremely hard on my database and doesn't work so well with users that don't have a strong internet connection.
So I'm looking for a solution that will 'push' data to my client. I have APE push-engine running on my server now, but I'm guessing Socket.IO is better for this? What if they're on 3G and they miss a status update?
Thanks in advance :)
I guess my answer may match what you need.
1st: You Have to Get Node.js to run the socket.io
BELOW IS SAMPLE CODE FOR SERVER:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8800); //<---------Port Number
//If No Connection / Page Error
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
//If there is connection
io.sockets.on('connection', function (socket) {
//Set Varible
var UserID;
var Old_FieldContent = "";
socket.on('userid', function (data) {
if(data.id){
UserID = data.id;
StartGetting_FileName(UserID)
}
});
//Checking New Status
function StartGetting_FileName(UserID){
//Create Interval for continues checking from MYSQL database
var myInterval = setInterval(function() {
//clearInterval(myInterval);
//MySQL Connection
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : '3306',
user : 'root',
password : 'ABCD1234',
database : 'test',
});
//Setup SQL Query
var SQL_Query = "SELECT FileName FROM status WHERE UserID = '"+UserID+"'";
connection.connect();
connection.query(SQL_Query, function(err, rows, fields) {
//Do if old result is, different with new result.
if(Old_FieldContent !== rows[0].FileName){
if (err) throw err;
//Display at Server Console
console.log('------------------------------------------');
console.log('');
console.log('Fields: ', fields[0].name);
console.log('Result: ', rows[0].FileName);
console.log('');
console.log('------------------------------------------');
//Send Data To Client
socket.emit('news', { FieldName: fields[0].name });
socket.emit('news', { FieldContent: rows[0].FileName });
//Reset Old Data Variable
Old_FieldContent = rows[0].FileName;
}
});
connection.end();
}, 500 );
}
});
BELOW IS CLIENT HTML & JS:
<!doctype html>
<html>
<head>
<title>web sockets</title>
<meta charset="utf-8">
<!-- URL PATH TO LOAD socket.io script -->
<script src="http://15.17.100.165:8800/socket.io/socket.io.js"></script>
<script>
//Set Variable
var UserID = "U00001";
var socket = io.connect('http://15.17.100.165:8800');
var Field_Name = "No Data";
var Field_Content = "No Data";
// Add a disconnect listener
socket.on('connecting',function() {
msgArea.innerHTML ='Connecting to client...';
console.log('Connecting to client...');
//Once Connected Send UserID to server
//for checking data inside MYSQL
socket.emit('userid', { id: UserID });
});
// Get data that push from server
socket.on('news', function (data) {
console.log(data);
writeMessage(data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
msgArea.innerHTML ='The client has disconnected!';
console.log('The client has disconnected!');
});
//Function to display message on webpage
function writeMessage(msg) {
var msgArea = document.getElementById("msgArea");
if (typeof msg == "object") {
// msgArea.innerHTML = msg.hello;
if(msg.FieldName !== undefined){
Field_Name = msg.FieldName;
}
if(msg.FieldContent !== undefined){
Field_Content = msg.FieldContent;
}
}else {
msgArea.innerHTML = msg;
}
msgArea.innerHTML = Field_Name +" = "+ Field_Content;
}
</script>
</head>
<body>
<div id="msgArea">
</div>
</body>
</html>
You should consider using push notifications, with the service provided for Android by Google as C2DM: https://developers.google.com/android/c2dm/
You will need to implement a PhoneGap plugin to handle the native notifications, and communicate them to your PhoneGap project that will then (and only then) query your server .
As K-ballo above points out, using a push notification plugin would be best.
Luckily, some good citizen on GitHub has done this already!
https://github.com/awysocki/C2DM-PhoneGap
Please note: the above C2DM plugin was built for PhoneGap v1.2, so if you are running a more up-to-date version you will have to tweak the native code a bit to get it working better.
Related
hello guys i developed an android app that http post req some data like latitude, longitude and IMEI to server that post in database. everything is working fine, but now comes the second part of the project. I need to make an web application that shows me on map a market with the lat and long saved in database and i don't understand how. I understood i should use querys but i don't understand who to use them.
this is my server side.
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var app = express();
//connect to mongodb:
/*mongoose.connect('mongodb+srv://tudorstanciulescu:19970826#test-
srqul.mongodb.net/test?retryWrites=true&w=majority', {useNewUrlParser:
true} );
*/
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/mydb";
//app.use(bodyParser.urlencoded({extended:true}));
//app.use(bodyParser.json());
app.use(bodyParser.json());
//var mongoose = require('mongoose');
app.post('/postBazaDate',(req,res)=> {
var latitudine = req.body.latitudine;
var longitudine = req.body.longitudine;
var imei = req.body.imei;
var dateTime = new Date();
;
var data = {
"latitude" : latitudine,
"longitute" : longitudine,
"imei" : imei,
"dateTime" : dateTime
}
// data.save()
// .then(item => {
// res.send("item saved to database");
// })
// .catch(err => {
// res.status(400).send("unable to save to database");
// });
MongoClient.connect(url, { useNewUrlParser: true }, function(err,
db) {
if (err) throw err;
var dbo = db.db("mydb");
dbo.collection("date_locatie").insertOne(data, function(err, res)
{
if (err) throw err;
console.log("1 document inserted");
});
});
i don't have any errors, everything is working fine, but i can't understand how to use the data from database in a script from an html
In Node.js, same place where you have added app.post
app.get('/getBazaDate',(req,res)=> {
MongoClient.connect(url, { useNewUrlParser: true }, function(err,
db) {
if (err) throw err;
var dbo = db.db("mydb");
dbo.collection("date_locatie").find({}, function(err, data)
{
if (err) throw err;
res.send(data); // here data is containing all saved data in array
//format
});
});
in html file
<!DOCTYPE html>
<html>
<body>
<h2>The = Operator</h2>
<p id="demo"></p>
<script>
const userAction = async () => {
fetch('http://localhost:3000/getBazaDate')
.then(response => response.json())
.then(json => console.log(json))
}
userAction();
document.getElementById("demo").innerHTML = response.json;
</script>
</body>
</html>
Simple REST Explanation
Ok so first is first, an html file is static and its contents can only be manipulated through javascript or css or someother language. Therefore, either you fetch the data before you load the page and send the data with the page , or you create an ajax call to get the data.
In a rest architecture you have GET , PUT , PATCH, POST ,DELETE Requests, each request is to either create ,read , or update the database.
A GET is to send data from server -> client, therefore a client requests data from the server and the server fetches and prepares the data for the client and sends it back.
Both PUT and PATCH updates the data in the database
A POST is to send from client -> server and save data
A DELETE to delete a row from the database
For more information about restfull you can visit this website: https://www.restapitutorial.com/lessons/httpmethods.html
or do a quick google search rest tutorial and you will find many !
Code Time
SERVER SIDE (USE ONE OF THESE) :
// app.js
// THIS GETS ONE ROW AND RETURNS OBJECT FROM THE DATABASE ACCORDING TO YOUR QUERY
app.get("/", (req,res,next) {
dbo.collection("date_locatie").find({}, function(err, res) {
if (err) throw err;
res.send(data);
});
})
// THIS GETS MANY ROWS AND RETURNS ARRAY FROM THE DATABASE ACCORDING TO YOUR QUERY
app.get("/", (req,res,next) {
dbo.collection("date_locatie").findAll({}, function(err, res) {
if (err) throw err;
res.send(data);
});
})
Now that your server is setup to get accept a GET REQUEST AND send back the data
All you have to do is call the url using an ajax call in javascript and your data will be sent to the client's pc.
To show the data you need to loop (if its array) and append data to HTML.
CLIENT SIDE :
In an html file you can write javascript in a script tag. This allows for the DOM elements to be manipulated. Supposed you have an empty with id locationData
and you want to fill it with the data that you saved
//index.html
//Assuming you are using jQuery
<div id="locationData"></div>
<script>
// WHEN HTML IS FULLY LOADED SENDS A GET REQUEST TO YOUR SERVER TO FETCH
// THE DATA
$( document ).ready(function() {
$.ajax({url: "http://localhost:3000/", success: function(result){
// PUTS THE DATA IN THE DIV WITH ID : locationData
$("#locationData").html(result);
}});
});
<script>
I have written an API for client side in node and I want that when a client hits the end-point only a string response is shown to client but as client hits the API an html file should be updated on the client side. Please let me know how to generate separate responses to client and admin from a single API in node.
app.get('/', function(req, res) {
res.sendfile('index.html');//sending file in response to client
});
// something like above is been done which sends response file to the client but i wants that it only updated and shown to the admin at the time of request.
const app = express();
const port = process.env.PORT || 3000;
const server = require('http').createServer(app);
//socket imported
const io = require('socket.io')(server);
//end-point 'ring'
app.post('/ring', (request, response)=>
{
console.log(request.body);
const data=request.body;
if(!data)
{
//if data is not sent then error status
return response.status(400).send('bad request');
}
// here i need to implement explicit responses
console.log((`data is----> ${data}`));
//here i'm emitting my json object to the html file
// this json object should be sent to the html to show
io.emit('message'{'requestbody':request.body,'status':'ringing'});
// sending success response to the client
response.status(200).send('ringing');
});
Index.html code
<body>
<script src=”/socket.io/socket.io.js”></script>
<script
//initializing socket
var socket = io();
//trying to recieve json object from socket
socket.on(‘message’, addMessages)>//calling the addMessage function
</script>
<script>
function addMessages(message)
{
//setting the text extracted from json object
$(“#messages”).append(`
//setting probeId
<h4> ${message.probeId} </h4>
//setting status
<p> ${message.status} </p>`)
}
</script>
//my 'index.html' file should be updated when user hits the ring api and user gets a string response.
I am pretty sure you don't need socket for what you need.
If my understanding of the question is good enough, you can just add a parameter to separate the type of return
app.post('/ring', (request, response)=>
{
console.log(request.body);
const data=request.body;
if(!data)
{
//if data is not sent then error status
return response.status(400).send('bad request');
}
if(data.returnType === 'html'){
response.sendFile(path.join(__dirname + '/index.html'));
} else {
response.status(200).send('ringing');
}
})
returnType is a POST parameter to separate the return types.
update :
if you want to update your index
app.post('/ring', (request, response)=>
{
console.log(request.body);
const data=request.body;
if(!data)
{
//if data is not sent then error status
return response.status(400).send('bad request');
}
if(data.returnType === 'html'){
response.sendFile(path.join(__dirname + '/index.html'));
} if(data.returnType === 'json'){
// Business logic here
let result = { a: 'aez' };
return response.json(result);
} else {
response.status(200).send('ringing');
}
})
And in your html
<body>
<script>
$("#envoyer").click(function(){
$.ajax({
url : 'send_mail.php',
type : 'POST',
data : 'dataType=json'
success: handle
});
});
function handle(result, status)
{
//setting the text extracted from json object
$(“#result”).append(`<div> ${result.a} </div>`)
}
</script>
</body>
I am trying to share datas between a cordova app (android) and a node server, but the client doesn't stop disconnect and reconnect...
Also, I can't get any information from the server (probably because the client disconnects too fast).
Here's my simple server :
io.sockets.on('connection', function (socket) {
console.log('new connected : ' + socket.id);
socket.emit('connected', {"data": "YEAAAAH"});
socket.on('slt', ( data ) => {
console.log(data);
});
socket.on("disconnect", () => {
console.log("disconnection");
});
});
And the code i use for the client app :
<script type="text/javascript" src="http://cdn.socket.io/socket.io-1.0.3.js"></script>
let socket = io.connect('http://MY-DOMAIN-NAME.com');
socket.on('connected', function (data) {
alert('connected');
socket.emit('slt', { data: 'slt' });
});
And a picture of the logs after 5 sec... :
logs
Do you have an idea how to fix that ? :)
Ok problem fixed : I messed up for linking my scripts :/
Im facing a problem reading the already set data from previous login after user abruptly switches from my App into another or restarts the phone. The data I've set after successful login does get saved in the SQLite database.
.controller('LoginCtrl', function($scope, $ionicPopup, $state,$http,ServerEndPoint,localStorageService,$cordovaGeolocation,$ionicActionSheet,dataShare,$ionicPush,loading,$rootScope,$cordovaSQLite) {
$scope.data = {};
//Does not work
$scope.init = function()
{
$scope.load();
};
if(localStorageService.get("tradie_id") !== null && localStorageService.get("phone_no") !== null) {
$state.go('menu.map');
}
//This is called from login form submit button click
$scope.authenticateUser = function(loginForm){
//Authenticating user from the server, after successful login
//This one works
$scope.addInfo(res.data.user_id,res.data.first_name,res.data.phone_no,status);
$state.go('menu.map');
}
$scope.addInfo = function(user_id,first_name,phone_no,status){
var query = "INSERT INTO user_data(user_id,first_name,phone_no,status) VALUES(?,?,?,?)";
$cordovaSQLite.execute(db,query,[user_id,first_name,phone_no,status]);
$scope.load();
}
$scope.load = function(){
$scope.alldata = [];
$cordovaSQLite.execute(db,"SELECT * FROM user_data").then(function(result){
if(result.rows.length)
{
for(var i=0;i<result.rows.length;i++)
{
$scope.alldata.push(result.rows.item(i));
}
localStorageService.set("user_id", $scope.alldata[0].tradie_id);
localStorageService.set("first_name", $scope.alldata[0].first_name);
localStorageService.set("phone_no", $scope.alldata[0].phone_no);
}else
{
console.log("No data found");
}
},function(error){
console.log("error "+err);
})
}
})
Any suggestions or pointers to a sample source code is highly appreciated. I'm using ionic version 1.
I think you didn't create or open the db when app ready first:
var db = $cordovaSQLite.openDB({ name: "my.db" });
I have an app i'm programming in Javascript/JQuery. I'm using PhoneGap and want to use localStorage to store the users credentials the first time they open the app and then autofill next time the user opens the app. I want to call the checkPreAuth() right when the page loads. But It's not calling my function. Can anybody help me?
Calling the function from login.html:
<script>
$(document).ready(function() {
checkPreAuth();
});
</script>
And the function in my digest_auth.js:
function checkPreAuth() {
var form = $("#loginForm");
var values = new Array();
var username = $('#username').val();
var password = $('#password').val();
if(window.localStorage["username"] == undefined && window.localStorage["password"] == undefined) {
localStorage.setItem("username", username);
localStorage.setItem("password", password);
alert('Saved username and password');
} else {
alert(username + ', ' + password);
}
}
Maybe this is the answer to your problem. I faced this problem and instead of using document ready of jquery, i used this:
JQuery document.ready vs Phonegap deviceready