We're using the samples at http://ucwa.lync.com/ and logging into our own topology.
After about 5 minutes, the logged in user goes "away" (availability is changed to "IdleOnline").
Once this happens, I am no longer able to push new presence states, such as "Online" to the server for the user. Busy" becomes "IdleBusy" while "DoNotDisturb", "BeRightBack" and "Away" all reflect the pushed status, but sending an "Online" returns to "IdleOnline".
After an additional 5 minutes, the availability changes to "Away", and at this point it is no longer possible to push new status updated to that user.
Changing notes still works fine.
To reset the locked "IdleOnline" state, I have to log the user off, and re-authenticate him.
(Note: this happens if the user doesn't have a Lync client keeping them alive)
Is there any other way to "reinitialize/poke" the user to return the presence state to Online, without having to restart the authentication process, or briefly authenticate the user on a separate process, which also returns to an active state for the one that was marked as "Away".
The behavior you are seeing is related to not making a POST request to reportMyActivity on a semi-frequent basis (~3-4min). This should keep the presence state of the user active. If you are still experiencing issues with presence, it may be necessary to also be issuing a pending GET request on the events channel.
Related
app.currentUser.delete deletes the Realm app user from the server side. However, it seems on other logged-in devices, and the data upload is still working with no auth error.
On other logged-in devices, re-launching the app would detect that the user has been deleted. I also tried to use isLoggedIn but for authenticated devices, it seems always stays “true”.
RealmApp.shared.currentUser?.isLoggedIn
How to detect Realm app user has been deleted on other existing logged-in devices?
User presence is a challenge with Realm; it doesn’t have a baked in user presence system.
While you can monitor when a user is Online or Offline by setting a flag or var when they log in or log out (for example) - there’s no way to monitor in-between or unexpected changes of presence or deletion.
For example, a user logs in - the app can set a var (synched with the server) to ‘Online’ that other devices are observing so their UI can be updated. Whenever that flag changes, other devices or users of the app will know about it.
But what if the app crashes, the user d/c’s for whatever reason or the user force-quits the app. That var is now “Stuck” to the on position and other devices would never know they were offline.
For this use case, you can add an observer to a object in Realm that stores user status and sync's with the server. If the user logs out on one of the devices they are logged into for example, the other devices could be notified of that change. If the user is deleted, a "is deleted" flag could be set which notifies other devices or users of that change.
Expanding on that a bit - Deleting a user could trigger a server side function to then followup with perhaps removing all of their data, cleaning up references or notifying other devices of that event.
In our design we have something of a paradox. We have a database of projects. Each project has a status. We have a REST api to change a project from “Ready” status to “Cleanup” status. Two things must happen.
update the status in the database
send out an email to the approvers
Currently RESTful api does 1, and if that is successful, do 2.
But sometimes the email fails to send. But since (1) is already committed, it is not possible to rollback.
I don't want to send the email prior to commit, because I want to make sure the commit is successful before sending the email.
I thought about undoing step 1, but that is very hard. The status change involves adding new records to the history table, so I need to delete them. And if another person make other changes concurrently, the undo might get messed up.
So what can I do? If (2) fails, should I return “200 OK” to the client?
Seems like the best option is to return “500 Server Error” with error message that says “The project status was changed. However, sending the email to the approvers failed. Please take appropriate action.”
Perhaps I should not try to do 1 + 2 in a single operation? But that just puts the burden on the client, which is worse!
Just some random thoughts:
You can have a notification sent status flag along with a datetime of submission. When an email is successful then it flips, if not then it stays. When changes are submitted then your code iterates through ALL unsent notifications and tries to send. No idea what backend db you are suing but I believe many have the functionality to send emails as well. You could have a scheduled Job (SQL Server Agent for MSSQL) that runs hourly and tries to send if the datetime of the submission is lapsed a certain amount or starts setting off alarms if it fails as well.
If ti is that insanely important then maybe you could integrate a third party service such as sendgrid to run as a backup sending mech. That of course would be more $$ though...
Traditionally I've always separated functions like this into a backend worker process that handles this kind of administrative tasking stuff across many different applications. Some notifications get sent out every morning. Some get sent out every 15 minutes. Some are weekly summaries. If I run into a crash and burn then I light up the event log and we are (lucky/unlucky) enough to have server monitoring tools that alert us on specified application events.
I am creating an application which has a follow mechanism where the followed user has to accept the request of a following (similar to private accounts on instagram).
I then want the following user to find out when the other user has checked a million times (every time the following user opens the screen if I did the query in viewDidLoad). However, the problem with this, is that there will be a lot requests which will expensive to me as I will have to pay for the requests to Parse so I want to minimise these queries.
Currently, the best thing I can think of is to check once a day at midnight for example but this doesn't seem very seamless.
Is there a better way of doing this?
For starters consider how stale you are willing to allow an app's view of the world to be and cache the response that long. If a user views that screen every 30 seconds you might only want to actually check with the server 5 minutes after the last successful response (or the last response which had 0 follow requests).
You might consider switching from this sort of "pull" polling where the client decides when to ask the server if anything has changed to a "push" model where the server can inform the client when a change occurs. For example you can send a silent background push notification to a user's devices when they have a follow request, the app can then respond by performing your existing query.
You might still want polling or user triggered requests (like a "pull to refresh" gesture) as a fallback for missed notifications or devices with notifications disabled but you should be able to drastically reduce request volume.
In my app, I get Lync Presence of our employees through UCWA. It works fine, but I need to knock to Lync with reportMyActivity every 3-4 minute.
I don't need to get presence info at night when employees are not at work, so I stop reportingMyActivity at the end of the working day and resume at it's beginning. Then trying to extend presence subscription, and if I get 404, I create new presence subscription. But no presence updates after those manipulations.
Is it designed to work this way? How could I avoid reportingMyActivity at night?
If you don't do reportMyActivity your Application will be drained, because assumed inactive.
I think you only have two options then:
Keep doing reportMyActivity regurarly also at night, you'll just stop extending presence subscription. Very likely you'll have to manage access token expiration too, which is normally 8 hours valid
You let the App shut down, and a complete new token acquisition, Application creation, presence subscription flow will start next morning
I would like to capture the following parameters:
lastAccessedTime - The time when the user visited the site the last time (usually shown during the login process)
isOnline - A boolean to represent if a user is online or not.
a. Would it make sense to have these variables as part of the User table itself or should this be handled via a separate user audit table?
b. If certain SOAP / REST API's expose the functionality via API calls, how do you track the above parameters (e.g. Would you modify the lastAccessedTime in such cases - this might confuse the user if he logs into the portal, isOnline bit also will not make sense if the user does API calls).
I would create a session table that links back to the user. Instead of an isOnline field, I would just run a query for sessions that have been active within the last x amount of time. I would also update that session field with each request, even if that request is coming through an API.
This does create some overhead in pruning the session table, but you also don't clutter up your user table with non-user information, which can't be pruned.
Make the lastTimeActive a field in the user table, and update it with each page access. Your "Users Online" list is all users whose lastTimeActive is within 5 minutes.
I would create another table (userid, lastTimeActive), and frequently update & check the table.
// update
update onlineusers set lastTimeActive = getdate() where userid=1234
// check
delete from onlineusers where lastTimeActive < dateadd(minute,-5,getdate())
The biggest problem with tracking user presence (onine/offline) over HTTP is how to determine when the user has gone offline.
It's easy to determine when the user has come online - the mere presence of an authenticated request assumes that the user is active. However, since HTTP is stateless, the lack of a subsequent request can mean either that the user is gone offline, or that the user is online, but just hasn't done anything specific with your app recently.
Thus the best guess you can make is to have a timeout and if the user has not made a request during that timeout, to switch to offline state.
The simplest implementation would be to have a lastTimeActive, as Jonathan Sampson suggested. However, this won't give you the length of the user session, only an approximation of who's online at this moment.
More complex approach would be to have lastTimeActive and lastTimeLoggedIn. LastTimeLoggedIn is set at the time of first auth request that is more than 5 minutes from a previous auth request. A user is considered online, if there was an authenticated request in the last five minutes. The session length for the user is the time difference between lastTimeActive and lastTimeLoggedIn.
If your app also offers the choice of logging out to the user, you chouls consider that action also as going offline. However, unless your app is a banking app, chances are the users will just close their browser.
Also, avoid any background threads for updating the offline/online status of your users. You should be running the logic above only when there's an explicit request about the status of particular user and you should be updating only the users you were asked for.