Angularjs Phonegap Android using Websockets - javascript

I don't even know how to explain this directly, but I'll try.
Intro
I'm building a Phonegap App with angularjs, and I'm trying to stitch up WebSocket messages to update my UI. I used to have services that communicate with the server periodically and change their data accordingly and it was working pretty well. An example:
Service1.js:
var applyUpdate = function (
angular.extend(instance, data);
if (!$rootScope.$$phase) $rootScope.$apply();
};
this.update = function () {
DataProvider.get('getThermostatSettings', {}, applyUpdate, function(){}, true);
}
So basically I was simply calling the "update" function every 5 seconds, receiving data from the server and updating this service. The controllers would then simply access this service, and everything was working.
The problem
The problem now, is that I stitched up a WebSocket Interface written in java, that handles all the websocket implementation for me. I took it from: https://github.com/ziadloo/PhoneGap-Java-WebSocket . It basically registers an Javascript Interface accessible from Javascript to communicate with java.
Everytime I have a change now, I simply push a string from the server via the WebSocket saying that it should update, and then I call the "update" function from the service in my javascript, instead of querying for data periodically, which is just stupid.
The WebSockets are working well. I can see the message coming, I call the update, it fetches everything correctly from the server, the "update" function calls then the "applyUpdate" with the correct values and etc, even the "$rootScope.$apply" gets called.
But all updated data inside the angular Service is not visible! It seems that all these changes are being run in a different thread!?!?. I know javascript is single threaded, but it just seems so.
Let me put this in a better way: I have the impression that as soon as the WebView calls the javascript callback function, I have a different javascript "thread" running, and nothing outside it can be accessed
More about it
I wrote a function that simply outputs a number every 5 seconds. The websocket updates this number. And my output is the following:
N: 1
N: 1
Then after the WebSocket pushes the data with a new Number (2), I get TWO prints:
N: 1
N: 2
N: 1
N: 2
N: 1
N: 2
Anyone has any pointers about this? Anyone tried doing something similar? I'm no angular pro, but it just seems that everything gets messed up as soon as I get a callback from the java interface.
I have already looked at: Angularjs model changes after websocket data push from server and my code looks very similar. The only problem I think is this callback from Java.
Thank you
Update : It's a problem with AngularJS. If I set this variable in a window global variable, everything get's assigned normally. Is it possible that Angular is somehow creating two different $scopes?
Update[2]: Just to be a bit more clear: In the browser, everything works as expected. Only when I run it in the emulator that this thing gets messed up.

It's entirely possible for Angular.js to be making two $scopes. Just see the debugging in this screencast.
It may help to show all the $scopes on the page.
You should also be aware that websockets on mobile aren't the best idea. Crashes and failures seem to be pretty probable, based on that talk (by a Nodejitsu employee with expertise in websockets).

Related

Detecting changes on database table column status

I am having a project in Laravel. In database I have a status column, which shows if exam is started or not. I had an idea in the waiting room checking every single second if the status was changed or not, if changed to 1, when the exam starts, but I am so new to Laravel and everything else, that I even don't get the main idea how I could do this, I don't ask for any code, just for the lead, to move on. yeah, hope someones gets me. Thanks if someone answers me.
Check about laravel cron jobs. You will need a class implementing ShouldQueue interface and using Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
With regards to the storage of the jobs i do recommend Redis or SQS.
In order to keep monitoring the queue in production think about installing supervisor.
Further information here: Queues
Your plan can work, it is called polling.
Basically, you will want to call
setInterval(function() {
//your code here
}, 1000);
setInterval is a function that receives two parameter. The first is a callback function, that will periodically be executed and the second is the length of the period in milliseconds (1000 milliseconds is a second).
Now, you will need to implement your callback function (Javascript, of course) to send an AJAX request to a Laravel action. You will need to look into XMLHttpRequest and its usages, or you can use some libraries to simplify your task, like jQuery or Axios.
On Laravel's side you will need to implement an action and a Route for it. (read this: https://appdividend.com/2022/01/22/laravel-ajax/)
Your Laravel will need to load data from your database, you can use Eloquent for this purpose or raw queries and then respond the POST request with the result.
Now, in your Javascript at the AJAX request's code you will need to have a callback function (yes, a callback inside a callback) which will handle the response and the the changes.
What about leveraging Observers? Also instead of having a status boolean, you could take a similar approach that Laravel has done for soft deletes and set exam_started_at. This way you can also keep track of time stamp and state all in one column. Also, observers are immediate rather than pushing them into a queue. Then generate a websocket event that can report back to your front end, if needed.
check out Laravel observer and soft delete documentation.
I know you specified "when the column on db changes..." but if it's not a strict-requirement you might want to consider implementing event-based architecture. Laravel has support for model events, which essentially allows you to run certain assertions and controls when a model created, updated, deleted etc.
class Exam extends Model
protected static function booted()
{
static::updated(function ($exam) {
if($exam->status=='your-desired-status'){
//your actions
}
//you can even in cooperate change controls
if ($exam->isDirty('status')){
//means status column changed
});
}
}
Of course this solution applies only if Database in question is in Laravel's reach. If database data changes outside the Laravel application these event listeners won't help at all.

Recovering identity in Blazor application

I have a Blazor server side application with a custom identityprovider.
Whenever I need to recover the identity I do so from the session storage using javascript.
This all works well.
But now I have added an upload control and I have embedded it with <CascadingAuthenticationState> to see if the identity was still known until that point, which it is.
Once I try to upload a file it makes a call to a controller using routing and that's where it goes haywire.
Once I enter the constructor of the controller the identity is null.
All attempts to recover it using javascript result in
JavaScript interop calls cannot be issued at this time. This is
because the component is being statically rendered
While I am familiar with this error message, I am puzzled why this happens because the render mode of the application is Server and not ServerPrerendered.
Is it because I am in a post event?
I've also played with several ways passing the httpcontext but that's also null.
Basically what I'm trying to accomplish is that I need my token there to call an API, but I've lost all track of who I am at that point.
I can think of ugly solutions like passing it in the URL, but that's not safe at all.
Or store it in a singleton with a lock or something like that, but those are all fugly solutions.
Can anyone kick me into right direction? I feel like I'm running into a very large, very dark forest now.
The vendor of the component added a new event to add custom headers, so now my problem is solved.

Meteor js publish and subscribe is very slow to react

I have used meteor publish and subscribe method to interact with client and server. Now according to my scenario I am using D3 js to generate a bar chart and as soon as the data is entered in mongo db collection I am using a client side function to generate a bar chart. My issue is that publish and subscribe is too slow to react. And even if I limit the number of documents returned by mongodb, the issue still persists. It is also inconsistent i.e. it will react under 1 second sometimes and other times it will take 4-5 second. Please guide me on what to do and what is wrong with my implementation.
Here is the server side code,
Test = new Mongo.Collection("test")
Meteor.publish('allowedData', function() {
return Test.find({});
})
and here is the client side code,
Test = new Mongo.Collection("test")
Meteor.subscribe('allowedData');
Meteor.setTimeout(function() {
Test.find().observe({
added: function(document){
//something
},
changed:function(){
//something
},
removed:function(){
//something
},
})
From your comments I see that you need a report chart which is reactive. Even though it is your requirement, it is too expensive to have a chart like this. In fact when you system grows bigger, say you have around 10000 documents for one single chart, this kind of chart will crash your server frequently.
To work around this problem, I have two suggestions:
Define a method that returns data for the chart. Set up a job/interval timer in client to call that method periodically. The interval value depends on your need, 10 seconds should be fine for charts. It is not completely reactive this way, you only get the newest data after an interval but it is still better than a slow and crash-frequent system. You could find good modules to manage job/timer here.
Use this Meteor package meteor-publish-join (disclaimer: I am the author), it is made to solve the kind of problem you have: the need to do reactive aggregations/joins on a big data set and still have a good overall performance

Syncing Database and Javascript

I'm working on a real-time JavaScript Application that requires all changes to a database are mirrored instantly in JavaScript and vise versa.
Right now, when changes are made in JavaScript, I make an ajax call to my API and make the corresponding changes to the DOM. On the server, the API handles the request and finishes up by sending a push using PubNub to the other current JavaScript users with the change that has been made. I also include a changeID that is sequential to JavaScript can resync the entire data set if it missed a push. Here is an example of that push:
{
"changeID":"2857693",
"type":"update",
"table":"users",
"where":{
"id":"32"
},
"set":{
"first_name":"Johnny",
"last_name":"Applesead"
}
}
When JavaScript gets this change, it updates the local storage and makes the corresponding DOM changes based on which table is being changed. Please keep in mind that my issue is not with updating the DOM, but with syncing the data from the database to JavaScript both quickly and seamlessly.
Going through this, I can't help but think that this is a terribly complicated solution to something that should be reasonably simple. Am I missing a Gotcha? How would you sync multiple JavaScript Clients with a MySQL Database seamlessly?
Just to update the question a few months later - I ended up sticking with this method and it works quite well.
I know this is an old question, but I've spent a lot of time working on this exact same problem although for a completely different context. I am creating a Phonegap App and it has to work offline and sync at a later point.
The big revelation for me is that what I really need is a version control between the browser and the server so that's what I made. stores data in sets and keys within those sets and versions all of those individually. When things go wrong there is a conflict resolution callback that you can use to resolve it.
I just put the project on GitHub, it's URL is https://github.com/forbesmyester/SyncIt

Is it possible to complete the loop from browser->java->c++->java->browser?

I've got a question about data flow that is summarized best by the image below:
I've got the data path from the UI (WaveMaker) down to the hardware working perfectly. The question I have is whether I'm missing something in the connection from the Java Service to Wavemaker.
I'm trying to provide information back to Wavemaker from the HW. The specifics of shared memory and semaphore signaling are worked out already. Where I'm running into a problem is how to get the data from the Java Service back to WaveMaker, when it hasn't specifically requested it. My plan was to generate events when the Java Service returned, but another engineer here insists that it won't work, since there's no direct call from Wavemaker and we don't want to poll.
What I proposed was to call the function after the page loaded, allow the blocking to occur at the .so level, as shown below, and then handle the return string when the call returned. We would then call the function again. That has the serious flaw of blocking out interaction with the user interface.
Another option put forth would be to use a hidden control, somehow pass it into Java, and invoke an event on it from Java, which could then be made to execute a script to update the UI with the HW response. That keeps the option of using threads alive, and possibly resolves the issue. Is there some more elementary way of getting information from Java->JavaScript->UI without it having been asked for?

Categories