Overuse internet connection with app - javascript

I am creating android application, using the PhoneGap platform. I have tested the use of resources by the application and I noticed that uses a lot of free 3G. In comparison to an application such as whatsapp, using too much connection.
My app is a chat, and I use javascript to make requests to refresh messages. Following the javascript that takes care of this:
var refreshShout = setInterval(app.ajaxFunction, 1000);
[...]
ajaxFunction: function () {
var shoutbase = $('.shoutbox');
if (shoutbase) {
$.get('http://edonetwork.altervista.org/Magnitude/log.php', function (data) {})
.done(function(data) {
$(shoutbase).html(data);
})
.fail(function() {
$(shoutbase).html('<div class="alert-internet">Ops... Occorre una connessione ad internet per usufruire dell\'App!</div>');
});
}
}
In log.php page there are all existing messages taken with MYSQL query from the database of altervista.
Below is the query that is executed:
$dati=mysql_query(" SELECT * FROM `Shoutbox` ORDER BY `Shoutbox`.`ID` DESC LIMIT 0 , 30 ");
How can I limit the use of the internet? As currently is excessive! But I think all chat app continue to make requests but why are more performant?
Thank you.

Related

Better way to schedule cron jobs based on job orders from php script

So I wrote simple video creator script in NodeJS.
It's running on scheduled cron job.
I have a panel written in PHP, user enter details and clicks "Submit new Video Job" Button.
This new job is saving to DB with details, jobId and status="waiting" data.
PHP API is responsible for returning 1 status at a time, checks status="waiting" limits query to 1 then returns data with jobID when asked
Video Creation Script requests every x seconds to that API asks for new job is available.
It has 5 tasks.
available=true.
Check if new job order available (With GET Request in every 20 seconds), if has new job;
available=false
Get details (name, picture url, etc.)
Create video with details.
Upload Video to FTP
Post data to API to update details. And Mark that job as "done"
available=true;
These tasks are async so everytask has to be wait previous task to be done.
Right now, get or post requesting api if new job available in every 20 seconds (Time doesnt mattter) seems bad way to me.
So any way / package / system to accomplish this behavior?
Code Example:
const cron = require('node-cron');
let available=true;
var scheduler = cron.schedule(
'*/20 * * * * *',
() => {
if (available) {
makevideo();
}
},
{
scheduled: false,
timezone: 'Europe/Istanbul',
}
);
let makevideo = async () => {
available = false;
let {data} = await axios.get(
'https://api/checkJob'
);
if (data == 0) {
console.log('No Job');
available = true;
} else {
let jobid = data.id;
await createvideo();
await sendToFTP();
await axios.post('https://api/saveJob', {
id: jobid,
videoPath: 'somevideopath',
});
available = true;
}
};
scheduler.start();
RabbitMQ is also a good queueing system.
Why ?
It's really well documented (examples for many languages including javascript & php).
Tutorials are simple while they're exposing real use cases.
It has a REST API.
It ships with a monitoring UI.
How to use it to solve your problem ?
On the job producer side : send messages (jobs) to a queue by following tutorial 1
To consume jobs with your nodejs process : see RabbitMQ's tutorial 2
Other suggestions :
Use a prefetch value of 1 and publisher confirms so you can ensure that an instance of consumer will not receive messages while there's a job running.
Roadmap for a quick prototype : tutorial 1... then tutorial 2 x). After sending and receiving messages you can explore the options you can set on queues and messages
Nodejs package : http://www.squaremobius.net/amqp.node/
PHP package : https://github.com/php-amqplib/php-amqplib
While it is possible to use the database as a queue, it is commonly known as an anti-pattern (next to using the database for logging), and as you are looking for:
So any way / package / system to accomplish this behavior?
I use the free-form of your question thanks to the placed bounty to suggest: Beanstalk.
Beanstalk is a simple, fast work queue.
Its interface is generic, but was originally designed for reducing the latency of page views in high-volume web applications by running time-consuming tasks asynchronously.
It has client libraries in the languages you mention in your question (and many more), is easy to develop with and to run in production.
What you are doing in a very standard system design paradigm, done with Apache Kafka or any queue based implementation(ex, RabbitMQ). You can check out about Kafka/rabbitmq but basically Not going into details:
There is a central Queue.
When user submits a job the job gets added to the Queue.
The video processor runs indefinitely subscribing to the queue.
You can go ahead and look up : https://www.gentlydownthe.stream/ and you will recognize the similarities on what you are doing.
Here you don't need to poll yourself, you need to subscribe to an event and the other things will be managed by the respective queues.

Ionic 5 IOS & Stripe Payment Request Button - Stripe.js integrations must use HTTPS

I'm trying to add a Payment Request Button to my Ionic 5 app. However, no matter how I run the app, I always get the following message and the button won't show.
[warn] - You may test your Stripe.js integration over HTTP. However,
live Stripe.js integrations must use HTTPS.
I'm loading the Stripe API over https
<script src="https://js.stripe.com/v3/"></script>
I've imported it in to my page
declare var Stripe;
// Check the availability of the Payment Request API first.
const prButton = elements.create('paymentRequestButton', {
paymentRequest,
});
paymentRequest.canMakePayment().then(result => {
if (result) {
prButton.mount('#payment-request-button');
} else {
document.getElementById('payment-request-button').style.display = 'none';
}
);
I've tried running it in Safari on Mac (running with --ssl and a valid certificate), Xcode Emulator, A Real iPhone and the result is always the same.
Also worth noting is that I'm using Capacitor, not Cordova. I've tried this in my capacitor.config.json but it had no effect.
"iosScheme": "https",
Update:
So it turns out that it's because the app runs with the local urlScheme of capacitor:// rather than https:// and the development team at Ionic currently have no plans to rectify this. Is there any way to make the Payment Request Button appear in a non-https environment?
After a lot of back and forth with Stripe's support team, I finally came up with a solution. A lot of what they said is included in this answer (placed in blockquotes). I've also included a code example that will hopefully help make sense of it.
I'm absolutely aware this is quite complex but unfortunately when not
using our official iOS SDK the process is quite involved, and as of
right now we don't have any official support for cross-platform
technologies like Ionic or React Native.
You must have an apple developer account, a merchant id and have a payment processing certificate uploaded to stripe (see steps 1->3 of https://stripe.com/docs/apple-pay#native)
You can use the cordova plugin (https://github.com/samkelleher/cordova-plugin-applepay#example-response) to generate an apple pay token. This will then be submitted to the V1 stripe API and exchanged for a Stripe Token. This is how Stripe's official IOS SDK works by tokenizing the PKPayment object in to a Stripe Token.
The paramaters to pass to the end point (not in the documentation) are;
pk_token (the string that you get from base64 decoding the
paymentData)
pk_token_payment_netowrk (paymentMethodNetwork)
pk_token_instrument_name (paymentMethodDisplayName)
pk_token_transaction_id (transactionIdentifier)
The names in the brackets are what is returned when using the cordova plugin.
Once you call this endpoint, you should get back a standard Stripe
token object(but the request will fail if you haven't registered your
Apple Pay payment processing cert as mentioned above). The Stripe
token(tok_xxx) can be used for payments as normal — the easiest way is
to convert it to a PaymentMethod by calling /v1/payment_methods with
type=card&card[token]=tok_xxxx , and then using it to confirm a
PaymentIntent.
Code Example
completeApplePay(resp){
const _this = this;
return new Promise((resolution, rejection) => {
$.post({
url: 'https://api.stripe.com/v1/tokens',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Bearer pk_test_xxxxxxxxxxxxxxxx")
},
data: {
pk_token: atob(resp.paymentData),
pk_token_payment_network: resp.paymentMethodNetwork,
pk_token_instrument_name: resp.paymentMethodDisplayName,
pk_token_transaction_id: resp.transactionIdentifier
},
success: function (data) {
resolution({
token: data.id
});
}
});
});
}
The (resp) parameter in the function above is the response from the cordova plugin;
const applePayTransaction = await this.applePayController.makePaymentRequest(order).then(resp => {
this.stripe.completeApplePay(resp).then((stresp:any) => {
// code goes here to store order in database etc
})
});
await this.applePayController.completeLastTransaction('success');

How to optimize $interval for real time notifications in Angularjs?

I am working on a social networking site. I have used following code to show the total notifications count in real time for a user.
Code:
function load_notifications(){
$http.get('http://localhost:3000/load').success(function(data){
$scope.totalNotify = data.total;
});
};
load_pictures();
$interval(function(){
load_notifications();
},300);
basically, this code checks the DB continuously at a given interval and if there is some change, it update the $scope value. But when I tried to check it with two different user in different browsers, it chokes the browser because of polling requests.
Is there any way to improve this method or have any other better alternative?
I am building my application using PHP and AngularJS. But I am open to other options for this module too.
This should be done using web sockets, not a polling ajax request.
JS: AngularJS and WebSockets beyond
PHP: How to create websockets server in PHP
Specifically, for web sockets using PHP, I would use Rachet.
A starting point for the PHP would be here: http://socketo.me/docs/hello-world
This hello world tutorial shows you basic javascript and PHP for interacting through Rachet.
awaitingResponse = false;
function load_notifications() {
if(!awaitingResponse) {
awaitingResponse = true;
$http.get('http://localhost:3000/load').then(function(response) {
$scope.totalNotify = response.data.total;
awaitingResponse = false;
}, function() {
awaitingResponse = false;
});
}
}
load_pictures();
$interval(load_notifications, 3000);
You could wait for 300 milliseconds after the answer was received, like this:
function load_notifications(){
$http.get('http://localhost:3000/load').success(function(data){
$scope.totalNotify = data.total;
setTimeout(function() {
load_notifications();
}, 300);
});
};
load_pictures();
load_notifications();
If you only use websockets, you will need to run a query every time to determine if anything has changed. I propose, use a real time DB.
You could use RethinkDB or Firebase with AngularFire. Those are realtime databases and will notify you when there is an update to any of those fields.
If you use RethinkDB, then you will also need to implement a websocket solution to notify the browser.

Run Native SQL Command in Azure Scheduler

I have been trying to achieve this myself for 3 days now and combined with my knowledge and searching have come up blank! Just edited and change the question to be a bit more "generic" but lead me to a solution.
Using the azure mobile services scheduler, JavaScript, I want to increment a value for each record in a table. Basically run "turns++" on the table, up to a maximum of a certain amount.
Is there a way to run a native SQL command in the azure scheduler?
For Example: Connect to the database and run "SELECT * FROM tableName" as this will let me run the increment that I need.
Alternatively is there a way, which I'm assuming more complicated, to run "for each" on records from the table and then update them with a field incremented?
Thanks in advance!
You CAN do this in Azure Scheduler! It provides a special mssql object which is initialized with connection to the current Database associated with the Azure Mobile Service. And it is extremely easy to use:
function sql() {
mssql.query('select top 3 * from TestTable', {
success: function(results) {
console.log(results);
for (var testObj in results) {
console.log('id: ' + results[testObj].id + 'name : ' + results[testObj].fname);
}
},
error: function(err) {
console.log("error is: " + err);
}
});
}
(Note that here 'sql' is just the name of my Scheduler Job) The only trick is, that if you want to access tables that are not part of the Standard Mobile Services API tables, you will have to explicitly grant read/write access to those tables following this nice guide.
The Result of execution of the above script is this:
Looping through the records you can do much more than just dumping to the log - i.e. execute other queries, etc. You can read the full documentation of the mssql object here.
Advice from MSDN Evangelist is that you cant do this in Azure Scheduler as it has only 3 action verbs - HTTP, HTTPS and Queue.
https://twitter.com/plankytronixx/status/516899252749225985
The solution is to use a free azure website and their new feature "web jobs". I did this with PHP but web jobs supports more languages.
$options = array("Database" => "database name",
"UID" => "userid",
"PWD" => "password",
"MultipleActiveResultSets" => false);
$conn = sqlsrv_connect($hostname, $options)or die ("Cannot connect to host");
sqlsrv_query($conn, "UPDATE schema.tablename SET turns = turns+1 WHERE turns < 10;")or die (print_r(sqlsrv_errors()));
More about Azure web jobs here http://azure.microsoft.com/en-us/documentation/articles/web-sites-create-web-jobs/

How to push notifications with angular.js?

I have been building a simple application to learn angular.js. So far I hooked up all the pieces in the MEAN stack and I am able to save and retrieve data from Mongo.
The app is essentially a todo list. The user can create a project and inside the project create "cards" with "todos" which can then be moved from state to state ("backlog", "in progress", "complete", etc.)
I would like to be able to push the notifications to all the people who are connected to tell their apps that a refresh is needed to get the latest todos. In other words, let's say that user A adds a new card to project A, I would like to send a message out to all users who are currently watching project A so that their application issues a project refresh to get the latest and greatest.
Any suggestions on how to proceed? Which technology, if any, I need to add to the MEAN stack to be able to do something like this?
Thanks in advance
Since you're on the MEAN stack, the standard recommendation in Node would be to use the Socket.IO API.
They provide the following example of two way messaging (which would facilitate your push messages very easily):
Client
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
Server
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(80);
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);
});
}
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
It will use websockets where possible, and fallback to AJAX long polling or Flash polling in browsers where there is no websocket support.
As for integrating with Angular, here's a good blog post on Socket.IO and Angular:
I'll be writing about how to integrate Socket.IO to add real-time
features to an AngularJS application. In this tutorial, I'm going to
walk through writing a instant messaging app.
If you're already working with Express, you should check out express.io.
It has a bunch of cool features like Session support and the ability to forward normal HTTP routes to realtime routes.
Here is a module we have written for getting AngularJS push notifications working in PhoneGap / Cordava (with full instructions):
http://www.scorchsoft.com/blog/free-angularjs-cordova-push-notification-plugin/
Simply download the example code and install. There is also code included for setting up the pushing component in PHP.
Why not with HTML5 Notification API....
export default class NotificationService {
/**
* Constructor of the class.
*
*/
constructor() {}
showPushNotification(title: string = '', message: string, iconPush) {
if (window.Notification && Notification.permission !== "denied") {
Notification.requestPermission(function(status) {
var n = new Notification(title, {
body: message,
icon: iconPush
});
});
}
}
}

Categories