I have an exception handler that runs when my code crashes, but I also need to send a msg to the server (parse.com) when this happens to let the server know the player has stopped playing,
void onUncaughtException(NSException *exception)
{
NSLog(#"uncaught exception: %#", exception.description);
[self playerLoggedOut];
}
The playerloggedOut line gives the error of undeclared identifier self.
How can I run the playerLoggedOut method when the exception happens?
How can I run the playerLoggedOut method when the exception happens?
You're not going to be able to start some lengthy process like establishing a network connection and sending a message. Your best strategy might be to save the information and send it when the app starts up again so that the server can update its records or whatever. Alternatively, have the client check in with the server every t seconds; if the server doesn't hear from the client within some interval like 2t, it assumes that the client has stopped functioning.
First of all: self is unknown, because you are not in a method, but a function. Functions do not run in an object context, therefore do not know self.
As mentioned before by Caleb, you should have a watch dog on server-side that automatically logs a player out, if the server gets no messages from the client for a while (in terms of seconds). To prevent from being logged out automatically, when the user is deactive (but still playing), you can implement a heart beat on the client using an instance of NSTimer.
As others have stated, don't try to do expensive things like talk to the Parse server in your exception handler.
In regards to what you are actually trying to achieve, you might want to re-think your architecture.
In the sometimes-connected world of mobile devices you will have your connection come and go. Instead of a boolean flag of IsLoggedIn, consider a UTC Date Time of LastUserActivity, and use a rule that says they are considered logged in if that last activity is in the last 5 minutes, or whatever is suitable.
If all access to Parse is done via Cloud Code then you could easily add a function call that sets the LastUserActivity to each method, then you can also avoid issues with time sync since you'll always be using the server's clock.
If you want to get a list of all online users, you can then just query for where LastUserActivity is greater than 5 minutes ago (or whatever limit you set).
Related
I have successfully implemented RemoteConfig in my application. Using the fetchWithCompletionHandler: to retrieve the values from the Firebase server.
However, some of the RemoteConfig parameters are required for the app to startup and I cannot give them meaning-full default values (using setDefaults).
So my idea is to block the app startup until fetchWithCompletion handler has returned the values (I can do that asynchronously while presenting a nice spinner to the user).
However, I am wondering, will fetchWithCompletion return values immediately?
Or could it be that the user will have to wait a long time for the values to be loaded?
It will not always return values immediately -- remember, you're making a network call to fetch those values from the server. Most of the time, this call is pretty fast, but depending on your user's network at the time, it could take a long time, and I believe the default timeout for this call is pretty long -- something like 30 seconds.
If you do want to block your app from running until this call is complete, I would recommend adding a loading screen (so your users know it's not frozen in case the call does take a few seconds), and implementing your own time-out that's a little shorter than the default.
Another option you might want to consider is the "Load up values for next time" approach, where you call activateFetched immediately (which will activate any values you might have downloaded in a previous session), then start a new fetch for values you can load the next time around. There's more info about it here if you're interested. This will mean your users' first session will have to be with default values, however, and it sounds like that might not be an option with your app.
I followed the guide in Delphi Labs: Datasnap XE - Callbacks ,
Callbacks seems to work good. Yet, leaving the client sides idle for more than a hour -- seems to cause clients callbacks stop working. I changed the server DSTCPServerTransport.KeepAliveEnabled, .KeepAliveInterval, .KeepAliveTime -- but it didn't help in any way.
Does anyone know how can I keep the clients connected overtime?
1: https://edn.embarcadero.com/article/41374
I also use Datasnap callbacks in several applications. My solution was to setup a timer that measures how long it takes for a specific message (eg '*ping') that was sent using BroadCastToChannel to be received by a registered callback on the same channel in the same application. I allow for 5 seconds in a mobile application, and if the echo of my ping isn't received in that time, I assume my callback isn't working anymore. I do what I call "recycle the callback". That is, I de-register the previous callback (causes no errors if it fails) and register a new one (my callback id's are timestamp based so they are all unique). My "ping timer" runs on 1 minute intervals which is often-enough for my application(s). This solution would be a lot of code to present here, so I hope my description will help you find a solution that works for you. Ask questions if you're unsure.
We have had this error recently reported by our clients and we on't know how we can fix this. We are using Delphi XE6 to develop our application and it connect to Firebird (v2.5) database as back-end. We also have used IBObjects for working with Firebird database in Delphi.
We have managed to replicate the error on the dev machine by stopping Firebird windows service before running a query but we haven't found a way to detect the connection lost in the code (e.g. by having an event) so as we don't know when this happens so we cannot reconnect to the database in the code either.
By the way, this is full error message if it helps:
ISC ERROR CODE:335544721
ISC ERROR MESSAGE:
Unable to complete network request to host "BON-VFS-01".
Error writing data to the connection.
Any help really appreciated.
From IBOBjects FAQ
Is there a way to detect a lost connection and try to reconnect
automatically, without user action?
Hook into the OnError event and look for the ERRCODE that denotes a
lost connection. Then, you can take whatever action you deem necessary
to deal with the problem. If the connection is lost you need to do a
disconnect and then connect again.
And from one of the base members of the IBObjects:
However, perhaps the "something" you are missing is that, if the
connection is broken by an external cause, the client application has
no way to know that it is not still connected. Its first knowledge of
that fact will come the next time it tries to access the server. The
API will report "Connection lost to database" and return GDSCODE
335544741, which is identified by the constant
isc_lost_db_connection.
At the point where this exception occurs, the TIB_Connection still
thinks it is connected - the Connected property will be true. If you
try to reconnect by calling Connect, you will get an IBO exception.
It is necessary to call Disconnect. This does not simply reset a
property. The Disconnect method performs all of the necessary cleanup
to invalidate the broken transactions and cancel any now invalid
postings, datasets and caches. Once Disconnect has completed its
work, you can then place a Connect call inside a retry loop and
attempt to get going again.
I do not know of a working example, but the simplest way to deal with
this is to write a RestoreConnection handler procedure that you can
call from your IB_Session.OnError handler whenever argument ERRCODE
returns isc_lost_db_connection.
Have your RestoreConnection procedure do whatever you need to do,
trying to call Connect and handling the exception that occurs if the
request fails, until no exception occurs. Test the Connected property
after each iteration. When Connected is finally True, you are in
business. You can drop out of the retry code and inform the user that
the connection has been restored - perhaps with a sound and/or a
message in the status bar, to avoid having to show a dialog box that
she has to respond to. (if you like the idea of sound and status bar
cues, you could devise "connection lost" warning sound and status bar
message code to run at the beginning of your handler procedure as
well...)
If these broken connections are a frequent occurrence, you might like
to consider making a distinctive custom cursor that you can display
while your procedure is running, and enclose the retry code in a
non-yielding BeginBusy...EndBusy block with UseCursor enabled and
BusyCursor set to use this special cursor image.
And if re-establishing a connection is likely to take a long time, or
to be temporarily impossible, you would need to provide the ability
for the user to intervene and choose not to keep trying. You can use
the session timer for this, enclosing your "busy" block inside
another iterative block the prompts the user to "Cancel" or "Keep
Trying", at reasonable intervals.
Source
Check out if their database file is located on mapped network drive. Even if database file path appear to be local to file system, when using embedded Firebird server, function isc_attach_database will return error code 335544721 on attempt to establish connection. Exactly that was happening on my VirtualBox guest Windows XP when I first share entire host D drive and then mapped it again as D drive in virtual guest OS.
Workaround will be to move database file to local partition drive.
check your query length
max query length is 8191 chars UTF-8
its solved my problem
connect your pc to the internet, and the problem will be fixed,but i don't how it works
I wants to do some operations even after closing the session (manual or by instant). I can do whatever I want when the user clicking the link 'logout' but I don't see any option do the same when the user suddenly closing the browser.
Hence, I am looking for any listener kind of things similar in Java.
in Java:
http://www.mkyong.com/servlet/a-simple-httpsessionlistener-example-active-sessions-counter/
Rails is stateless and doesn't support this type of behaviour directly.
If your requirement can only be satisfied with this type of logic, then I can think of a number of ways you could work around this:
Have the page continuously ping your server to let it know the
connection is still alive. Run a cron job every reasonable interval
to take whatever action you want on terminated sessions.
Or just say that any session not refreshed after 30 minutes or
something is considered terminated.
Create a javascript code run on page unload that notifies your app that
the browser is closing. This is obviously not foolproof (connection
drops, browser crashes, etc) and probably isn't viable.
I have a JSON database connection for my app, and it is set to load (refresh) on the app's initial launch. The JSON data is stored on the phone, and retrievable if no internet connection is discovered on relaunching the app--so there's always data in there.
If the user has a slow connection to the internet--as in patchy <3G--the app will hang. I would like to set a timeout that reverts the database to the saved information (as it would if there were no connection at all). Unfortunately, I think that setting the timeout in the wrong function could make the app crash.
I've read there's no publicly available class to determine a connection speed, but can anyone suggest alternatives?
You could set a timeout for the NSURLRequest, if thats what you're using. In the callback that handles the timeout you could fall back to your local copy of the data. Check the following answer provided by another user.
NSURLConnection timeout?
If you wanted to determine the actual connection speed, you could have your app download a piece of arbitrary data of fixed length, and record the time it takes to complete. This has its own flaws though. You would have to decide when to do this, and how frequently. It may also suffer from the problem that you are trying to solve. And, for example, if the user was on a train, their connection may be great one moment, and poor the next. I think that the timeout solution would work ok, it just means that the user has to wait a period of time before the app falls back to the local copy of the data.