I want to make 2 different quizzes, a monthly quiz and a daily quiz, so the daily quiz is shown every day to the logged in user and the monthly quiz every 30 days.
Any ideas how to implement this with html / javascript? I think I need a counter variable to proof counter < 7. How can I count the days between last quiz and now?
I asked somewhat a similar question a while ago and this is one of the responses I got. My question was more to with how to make use a wait X amount of days before they could leave a review on my ecommerce store. Hopefully this will guide you in the right direction.
As I understand your use case, you need a persistent storage method to remember how many days have passed since a particular action/thing. There are, in general, 4 methods of persistent storage:
1. Cookies:
Storage: Client Side
Specific: Unique to user machine and domain
Persistence Time: Can last forever unless the user specifically
deletes the cookie
Common Use Cases: Saved preferences
2. Session
Storage: Server Side (depends on driver)
Specific: Specific to user (but depends on driver)
Persistence Time: Usually expires in a couple of hours, but can be extended
Common Use Cases: Persistence layer from one request to another (like shopping cart, popup notifications after action triggers)
3. Caching
Storage: Server Side
Specific: Generally application specific (but can be user specific)
Persistence Time: Generally an hour to a couple of days
Common Use Cases: Application specific storage use cases (e.g. total number of hits, most popular pages, database query caching, view caching)
4. Database
Storage: Server Side
Specific: Can be user or app specific
Persistence Time: Forever until deleted
Common Use Cases: Longer term data persistence layer (e.g. user details)
Related
I have a configuration page where the user can select at what time to receive certain information from my API, for example they could select to get the information every day at 5PM or every Friday at 5PM. After this is set, the user should receive a Slack message at the time they defined, for example, every day at 5PM they would receive a message...
I save the user's timezone so that I can send the message to them in Slack at the correct time for them.
That being said, how can I schedule this message to send out from my node.js app? I would have a few users in the system, all who would have likely chosen different times so I would need a timer per user?
The only thing I can think of is scanning all users in the system, getting their selected time and then sending the message to them...but this doesn't seem scalable.
I'm not looking for a complete solution for this, just some pointers for how to design this sort of functionality.
I also looked into Slack scheduled messages but this isn't exactly what I'm looking for. Note: I can already send messages to Slack, I'm more interested in how to build the timer mechanism.
Thanks in advance!
EDIT:
Did a bit more research and it looks like node-schedule could be an option to schedule jobs: https://github.com/node-schedule/node-schedule#readme
With using this package, is the approach that I scan all users in my database at let's say midnight everyday and schedule jobs based on their settings...then those jobs execute at their scheduled time and the user receives the message in Slack. Is this a good approach?
For the core logic I would suggest something like this:
Store the timing of delivery (e.g. 5 AM ever Friday) for every user in your database
Then have a worker process that is running on a regular basis, e.g.
every 5 minutes
When it runs it checks if there are any due messages to be delivered
If yes it sends the message with your API information to the user and store the last time of sending for the user
This approach is resilient to downtime. It will just resume sending due messages once the worker process is running again after a downtime.
It is also scaleable: If needed you can run multiple worker processes (make sure to design your workers to support concurrent processing, e.g. with transactions)
Some additional things to consider:
Would limit the number of messages sent per run to avoid timeouts and having too many workers running in parallel
You need some error handling if sending message to Slack fails
To avoid timezone complexities I would suggest to convert all timings to UTC for processing in your app
Is this a regular task? In other words, it's executed every day at the same time for user X? If so, node-schedule seems fine, and it can run the same job regularly, you just have to set it up properly via a cron-like string (see the instructions in the README). If a user changes their setting, you then modify the previous job. The downside with node-schedule is that you need to set it up everytime your application is loaded, which can take a while and consume lots of resources if you have too many users.
Alternatively, if the number of users is big or you prefer to keep your application stateless, you can set a number of slots for sending these messages (and run that in a separate process from your main application). Let's say, a slot every 30 min. Then you set timers for those time slots (using node-schedule if you like, it will be just 48 timers), fetch the list of users for that time slot from the database, and send the messages.
Overall, NodeJS/JavaScript is pretty efficient with this sort of timer-based scheduling. If you want an in-depth dive into the reasons, see this: https://nodejs.org/de/docs/guides/event-loop-timers-and-nexttick/
You also need to consider what happens in case your application suffers from downtime. Should users be guaranteed to receive those messages, even if they are late? But that's another story :-)
I want to track that the user has played the game on my website for 15 minutes per day and for continuous 10 days if he misses one day then his needs to again start from day 1 using JavaScript and PHP.
I am getting stuck in the idea that how we can track the 15 minutes a day and 10 days for a specific user.
As #arkascha mentioned, tracking user involves using sessions and saving data to permanent storage (you can save into file for first time, but learn DB management - PHP is closely tied with this one)
But before that you need to ask YOURSELF with few questions
Why do need to check data about users on your site? Remember that most of time users don't spend on web page, maybe it's better to check their requests to your site?
What type of network environment you're using. Is your website is opened for entire world (e.g. Internet) or you're located in small network with network access rules?
How you should identify your users? By IP or some kind of name?
Answering 3rd question can be done via requesting phpinfo() function and checking following variables $_SERVER['USERNAME'], $_SERVER['REMOTE_USER'], $_SERVER['REMOTE_HOST'], $_SERVER['REMOTE_ADDR']
Learn sessions (start from manual http://php.net/manual/en/function.session-start.php)
And remember - you should ask questions about particular problems (for example, "Session variables are not storing on PHP 7.x, Ubuntu XX, Apache 2.4.x"), NOT general ones (please write the code for me)
I'm developing a quiz with stopwatch, to calculate how much time user spent answering the quiz. But it's hackable by the user if the user refresh the browser.
Hmm what should I do? should I save the the counter to localstorage every seconds? and resume?
No, local storage is entirely under the control of the user as well.
You'll need to track the information server-side: Have the server record when user X started task Y, and have the server record when they completed it. Nothing you can do client-side will be resistant to an even modest attempt at bypassing.
Even the server approach can be susceptible to bypassing by bad actors (for instance, I sign up for multiple accounts, get all my answers together, and then sign up "for real" and take the quiz in record time). You'll always be in an arms race (IP checking, etc.), but at least you'll have some small chance by using something somewhat outside the user's control.
I have a million Dinosaur Users all logged in.
Dinosaurs want to see when other Dinosaurs update their profile in real time, so they are hooked into the NodeJS/Mongoose model as:
dinosaur.schema.post('save', function (doc) {
socket.emit('dinosaur:save', doc);
});
where socket is the socket of the connected Dinosaur.
Dinosaurs are also going to see real time updates from several other things. Maybe news, comments, etc etc.
So, my question, is there some instance where this emitting of events will grow large and impact performance?
On the client side, I'll have something like socket.on('dinosaur:save', function(){})... I destroy the listeners when not needed. BUT, if I'm listening to every dinosaur:save, I could theoretically be processing that for a million saves a second (say if every dinosaur updated their profile in the same second). It just seems like there's a better way to do that with large data sets.
I imagine there are several other events I may want to watch and I'm just wondering if there are some recommended methods for this kind of socket management.
EDIT: To be clear, I'm aware of rooms, but if I, for example, have a scrolling list of all nearby Dinosaurs in my area, I probably just want to hook into receiving all of the dinosaur:save events. So I'm still not sure.
Notifying a million of anything is a lot of packets and if the thing you're notifying occurs a lot, that's a lot of a lot and it's even more than a lot to try to show on screen.
The usual first things to consider are:
How real-time do these notifications really have to be? Can you batch up 60 seconds or longer of notifications into one packet per user per notification period?
Does every user really have to see every single change from every other user. You know there's absolutely no way that any user interface can present the state of a million other users. So, I'd argue that every user doesn't have to know about the state of every other user. Maybe if there's 1-50 other users, but not if there's a million.
Can you algorithmically determine which users state a given user might be interested in and only broadcast to them. For example, can you keep them up to date only on other users that are geographically near them?
Can you have a user interface where the user tells you which other users they want to track so you only update those? Or perhaps some combination of users they tell you about and users who are geograpnhically interesting to them. The point is that you can't watch a million users anyway so you're going to have to invent a UI that shows a lot less than that anyway.
You can always have a UI that will fetch the state of other users upon demand if the client doesn't already have that state, so you don't have to keep the state for all million users in each client (since it can't possibly all be shown at once anyway). If the user browses to see some things they don't already have, you just fetch it from the server via the socket or ajax call.
Oh, and at the scale you're talking about, you are probably going to need to have your user's connections spread out among several servers so you're going to have to handle that complexity too.
In case anyone comes across this in the future, here's the problem and my current solution.
We want real time updates. If you're on someones profile page, and t hey update it, show that. If you're viewing some catered result set, say, of user profiles, and any one of those users updates their profile, show that. If you're on another page and some counter changes, say, of users near you, show that. But, we aren't going to be on all these pages at the same time, so on the client side i don't even want to know about the other changes if I'm not on those other pages. This is the problem that could cause me to be notified of everything which could cause bandwidth issues, and a whole bunch of unecessary socket usage.
So, the way I'm solving my problem is using rooms. I'm using rooms over namespaces because namespaces are generally used for two mutually disjoint applications accessing the same socket resource. Rooms also just fit better with this application.
I've created a dynamic, on the fly room for every user profile page. When a visitor opens a profile page have the client call socket.emit("joinRoom", modelName + ":" + modelObj._id); and on the server handle that with socket.on('joinRoom', function(room) {
socket.join(room);
});. This automatically creates the room if there isn't one yet. And adds the user to it. modelName could be whatever we want. It's just a naming convention of how I split up the rooms. You can call rooms anything. BUT the important part is the ._id at the end. Using Mongoose, no two DB objects can have the same ._id, so this guarantees unique rooms.
When the owner of this profile page updates their information we call on the server:
io.sockets.in('Dinosaur:' + doc._id).emit("Dinosaur:" + doc._id + ":updated", doc); And receive that on the client side using
socket.on(modelName + ":" + modelObj._id + ":updated" , function(msg){
// do something
})
Viola, we have only sent this necessary information to the interested clients.
--
( A separate problem ) --
Using this approach, we can also deliver data pertaining to multiple users. if we have a catered result list of user profiles, for each profile, we can add the current user into the rooms of all of those catered result profiles. (So they're in a room belonging to _id X, _id Y, _id Z, etc.
The current user would then be in multiple rooms, all reflecting the immediate updates of those users, and therefore the entire catered result list, for whatever list it may be (perhaps it is "Dinosaurs nearby").
Another approach to this, especially if the list is somewhat more static, is to have the socket re-deliver the result set every X seconds, using the same socket, and just the same initial room.
In our application, we are painting navigation component using JavaScript/jQuery and because of authorization, this involves complex logic.
Navigation component is required on almost all authenticated pages, hence whenever user navigates from one page to another, the complex logic is repeated on every page.
I am sure that under particular conditions the results of such complex calculations will not change for a certain period, hence I feel recalculation is unnecessary under those conditions.
So I want to store/cache the results at browser/client side. One of the solution I feel would be creating a cookie with the results.
I need suggestions if it is a good approach. If not, what else can I do here?
If you can rely on modern browsers HTML 5 web strorage options are a good bet.
http://www.html5rocks.com/en/features/storage
Quote from above
There are several reasons to use client-side storage. First, you can
make your app work when the user is offline, possibly sync'ing data
back once the network is connected again. Second, it's a performance
booster; you can show a large corpus of data as soon as the user
clicks on to your site, instead of waiting for it to download again.
Third, it's an easier programming model, with no server infrastructure
required. Of course, the data is more vulnerable and the user can't
access it from multiple clients, so you should only use it for
non-critical data, in particular cached versions of data that's also
"in the cloud". See "Offline": What does it mean and why should I
care? for a general discussion of offline technologies, of which
client-side storage is one component.
if(typeof(Storage)!=="undefined")
{
// this will store and retrieve key / value for the browser session
sessionStorage.setItem('your_key', 'your_value');
sessionStorage.getItem('your_key');
// this will store and retrieve key / value permanently for the domain
localStorage.setItem('your_key', 'your_value');
localStorage.getItem('your_key');
}
Better you can try HTML 5 Local Storage or Web SQL, you can have more options in it.Web SQL support is very less when compared to Local Storage. Have a look on this http://diveintohtml5.info/storage.html