Just to set the background, I'm working on an app with Cordova + Sencha Touch and NodeJS + MongoDB as backend. Now I need to have some devices (tablets or smartphones) send some data to a central device (pc), that would to be done periodically or on demand. I'm trying to figure out what the best way of doing that is.
Just to make myself clear...
Device 2 <------ Device 0 -----> Device 1
|
|
v
Device 3
So with that illustration in mind: I'd need to have Device 1, 2 and 3 (tablet or smartphone) send their current location (along with some other information) to Device 0 (pc, server, etc). Keep in mind that there's actually gonna be a lot more than 3 devices, say 1500 or 2000.
What I thought was have them send that data periodically to a database and then query that database whenever it's needed. That would have to be done once every 30 seconds (or less) though.
I really have no idea of what the best way of doing this would be though, I suppose I could achieve this by setting a counter on the device's app and having it send the data to the database, but I'm certain there has to be some more efficient way.
The other option is having them send their data on demand, but that seems like more workload as there's a ton other devices (hopefully in the 10s or 100s thousands) that will have to ask those 2k devices for that data, and that could be whenever the user wants to.
So, are there any other ways of doing this that I'm missing?
EDIT
Just for the record, I ended up chosing the first option. Just record whatever status I needed on my db and query whenever I need to check for changes.
Related
I want to make a custom tracking system for web events. I have looked into multiple per-excsiting systems, but I want something terribly simple - yet very accurate.
I want to be able to track the following:
Page view even
Time on that page
or:
Video started playing event
Time of video watched
My first initial thought was to do a simple javascript reporting back to the server, but what happens if the user closes the window? How do I know they stopped viewing? And how can I get accurate measurements down to 1/10th of a second? So I thought of a websocket solution, as it know when a user has discounted. I ended up with Socket.io, but I want to make sure there is no better or smarter way to achieve this?
How would you approach his challenge? What is the smartest way to engineer this?
A Websocket connection which reports back to the server frequently was my first thought as well, but if you send 10 messages every second, even that might be too much for a websocket, especially when connectivity isn't top-notch.
Since the server doesn't require the information absolutely immediately, consider batching requests instead - save/update the information into Local Storage every 0.1 seconds, but don't send it to the server then - instead, every 30 or 60 seconds, or on pageload, take the current data in Local Storage and send it to the server, and clear Local Storage so that the next request a minute from now doesn't send duplicate data.
I would like to show a list of devices that a user has enabled push notifications for in their dashboard. In this list I would like to highlight the current device they are using if it's in the list or show a "Add this device" button if it's not in the list. So let's say the user has enabled push notifications on their phone and on their desktop. They log into the dashboard on their phone. Is there a way for me to tell that it's their phone? Also, what if they decide to block notifications in their browser or do a factory reset (my database won't sync obviously)? So what would be a good way to purge that old device from the list?
I'm doing this because I want a good user experience and I want to give users the option to toggle push notifications on/off per device through the dashboard without making them do it through the browser which could end up in them never re-enabling them again.
I was thinking maybe passing a hardcoded (but generated) id variable into the service worker?
let deviceId = 0;
But this seems really clunky. Is there a better way?
PS. My backend is PHP and MYSQL. Don't think it matters, but any answers with server-side code I'd prefer with those. I think this is all client-side though.
If the user resets the browser (device), you will only discover it by trying to send something and getting a 404. So it's not possible to always be able to show a list of devices with 100 % correct info if you're not spamming the user all the time. You could probably show something like the last time a push was delivered to a certain device, maybe that would be good UX-wise.
To detect which of the devices is the current one looking at the list, simply use some sort of an id that is saved in the db when the push subscription is created. Then hold on to that id in the device (browser) and based on that, make one of the items on the list pop up.
This question has cropped up a few times in various guises, but I've not seen an answer that satisfies my requirement or fills me with much confidence. Let me set the scene.
We currently have a web application, which allows users to submit responses to pre-set questions where the data ends up in an SQL Server database, we also have a Windows application that does the same thing but works in an offline capacity; i.e. it connects to the SQL Server, downloads the questions, allows the user to complete them offline and when they next have a network connection they can synchronise the data, uploading it to the SQL Server. Great!
As part of our development strategy, given HTML 5's offline capabilities and local storage,it seems perfectly sensible to attempt to consolidate these products into a single web application. This would mean we're able to work on a single code base, and this would also enable the application to run in a browser on most devices; platform independent.
Looking into this I see a couple of potential problems, I'd really appreciate a steer on these:
Users need the ability to login, in offline and on-line modes. This could mean we download the hash's of the all users usernames and passwords, or just those that have logged in whilst in on-line mode. However, even doing this there needs to be a way to check these and given that the Javascript is readable someone could easily reverse engineer their credentials. Yes you can obfuscate the code but this isn't infallible.
The data that needs to be stored locally could be highly sensitive; contain personal information etc. Therefore this also needs encrypting, at minimum AES 256.
Am I hoping for utopia? Is this something that's just not possible at this time? Do I need to be looking at another solution and dismissing this for the time being?
Any help from you lovely people would be much appreciated.
First the easier question 2: that is perfectly possible. You can generate the key on the device and on sync send it via https to your server which can decrypt the data then.
As for question 1 I'd say an offline login is not really feasible BUT do you actually need one? Once the questionaire is downloaded (which requires online mode, so requiring login is fine) you only need to transmit it on sync, where online is again required and you can ask the user for his login there, too. I'd not recommend to download any sensible user data (e.g. hashes) to the device.
What you can do is to cache the current user only after logging in online. This would mitigate the risk of enumerating the users in your local DB.
You then need to encrypt the user's data on the front-end, I'd go with a library that does the job for you (for example, RxDB). RxDB accepts a password (which you can generate on the fly) and based on it, encrypts your DB data. The user then fills in the form (does whatever he wants) and if all of the sudden the internet is gone, the user is still able to continue his work and that work must be added as pending requests in order to do the sync. (which you already have)
When the internet is restored, you're going to check whether the session has expired for the user and if so, prompt the user to log in again and do the sync if it was the same user. If it's still there, perform the sync.
My advice based on my personal experience for the offline part.
You can create a local variable that allows the user to login once using internet for the first time then he will be able to auto login for several times as much as you decided in the local variable and when the value is 0 he will need an internet again to get another offline access for the same value you decided before.
so, in a small words. offline counter that will need an internet Only after many offline logins (when the counter decrease to 0)
Flowcharts
I'm trying to build a single page web app using Backbone. the app looks and behaves like a mobile app running on a tablet.
The web app is built to help event organizers manage their lists of people attending their events, and this includes the ability to search and filter those lists of attendees.
I load all attendees list when the user opens the attendees screen. and whenever the user starts to search or filter the attendees, the operation happens on the client side.
This way always works perfectly when the event has about ~400 attendees or less, but when the number of attendees gets bigger than that (~1000), the initial download time takes longer (makes sense) .. but after all data is loaded, searching and filtering is still fast relatively.
I originally decided to go with the option of fully loading all the data each time the app is loaded; to do all search operations on the client side and save my servers the headache and make search results show up faster to the user.
I don't know if this is the best way to build a web/mobile app that processes a lot data or not.
I wish there's a known pattern for dealing with these kinds of apps.
In my opinion your approach to process the data on the client side makes sense.
But what do you mean with "fully loading all the data each time the app is loaded"?
You could load the data only once at the beginning and then work with this data throughout the app lifecycle without reloading this data every time.
What you also could do is store the data which you have initially fetched to HTML5 localstorage. Then you only have to refetch the data from the server if something changed. This should reduce your startup time.
I have a web application to be run on mobile phones that when open continuously generates data (a few kilobytes every few seconds or every few minutes depending on settings) and needs to push it to a server in real time. No data is ever sent from the server to the browser.
My main concern is to make this submission battery efficient, a few seconds of delay is totally fine.
I envisaged two solutions:
Periodically do a POST to the server with the data (to avoid having a permanent connection to maintain)
Have an open websocket and periodically send messages (to avoid the weight of an http request)
Which one is the most efficient for the battery? Are there other strategies that I am missing?
Actually my app will be hosted on heroku, which does not supports websockets yet, resulting in long polling, thus for the moment I'll assume it is better to POST on demand, but I am wondering if it could be an option in the future (or maybe this assumption is wrong).
Android
On Android devices, there are three different network radio states as the documentation says:
The state machine for a typical 3G network radio consists of three
energy states:
Full power: Used when a connection is active, allowing the device to transfer data at its highest possible rate.
Low power: An intermediate state that uses around 50% of the battery power at the full state.
Standby: The minimal energy state during which no network connection is active or required.
While the low and idle states drain significantly less battery, they
also introduce significant latency to network requests. Returning to
full power from the low state takes around 1.5 seconds, while moving
from idle to full can take over 2 seconds.
The device changes from Full to Low after an idle time of 5sec, then from Low to Standby after another 12sec.
The above link also covers some best practices for battery friendly connections, although it doesn't say anything specific about Websockets.
iOS
I couldn't find such specific documentation on iOS devices, but the model seems to apply in a similar way:
Cellular and Wi-Fi radios are designed to power down when there is no
activity. Depending on the radio, though, doing so can take several
seconds. If your app transmits small bursts of data every few seconds,
the radios may stay powered up and continue to consume power, even
when they are not actually doing anything. Rather than transmit small
amounts of data more often, it is better to transmit a larger amount
of data once or at relatively large intervals.
So what?
In general, you should probably use short POST requests and send data as seldom as possible, so the radio can power down in between.