Open sarsonj opened 12 years ago
Hello,
I also have this problem. Some times the Framework doesnt even connect to the server. I didnt make any investigation on that.
Could you share your fix so I can test it in my implementation?
Yeah I am having the same issue, is there a fix?
I'd like to see the fix as well.
I'm having the same exact problem- does anyone know of a solution?
Currently, I implemented "hacky" solution using Rechability example from Apple - http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html
Simply when I detect no network, I close XMPP socket using [asyncSocket disconnect];
The XMPPReconnect plugin then handles connecting correctly.
However, this is quick hack, It should be implemented in XMPPReconnect. Now when it is confirmed as problem of more people, I will look to XMPPReconnect to fix it here.
sarsonj, I tried your solution, but it doesn't seem to fix my problem. Here's how I'm reproducing the issue:
2012-08-29 01:54:47.540 medigram[48306:c07] -[MGXMPPManager xmppStream:socketDidConnect:] [Line 243] XMPP Stream Socket did connect 2012-08-29 01:54:47.768 medigram[48306:c07] -[MGXMPPManager xmppStream:willSecureWithSettings:] [Line 250] XMPP Stream willSecureWithSettings:{ } 2012-08-29 01:54:48.109 medigram[48306:c07] -[MGXMPPManager xmppStreamDidSecure:] [Line 302] XMPPStream Did secure 2012-08-29 01:54:48.186 medigram[48306:c07] -[MGXMPPManager xmppStreamDidConnect:] [Line 307] XMPP Stream Did Connect 2012-08-29 01:54:48.186 medigram[48306:c07] -[MGXMPPManager xmppStreamDidConnect:] [Line 315] Error authenticating with password: xxxxxx : Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the stream is connected." UserInfo=0x8514d70 {NSLocalizedDescription=Please wait until the stream is connected.}
The interesting thing is that xmppstream thinks it's not connected, even though the authenticatewithpassword function is being called from the xmppStreamDidConnect delegate function.
yding did you try without using the secure method?
It could be a bug with the secure feature that is not setting all the variables correctly.
jonasman, we ended up fixing it with sarsonj's method. Changing the security didn't seem to help.
Can you provide the code you have implemented?
any news in this topic?
It seems that the rechability is the way to go, what about the integration with that class and XMPPStream/reconnect or even in the async socket?
I'm having the same problems. When leaving the app for a long time, or even in the background, It sometimes randomly loses the connection and can't reconnect. What's the best way to force a reconnection?
I think the problem is with the async socket that doesn't care about the reachability at all.
so, was there any development in this case or should I use sarsonj's workaround?
Ok, the workaround does help when app is activated, but when it's in background it still doesn't reconnect.
I have tested whats app for ios. Even that wont connect in background once the internet connectivity is gone and comes back. However KIK messenger does connect. Weird problem.
On Tue, Feb 5, 2013 at 7:07 PM, misha2400 notifications@github.com wrote:
Ok, the workaround does help when app is activated, but when it's in background it still doesn't reconnect.
— Reply to this email directly or view it on GitHubhttps://github.com/robbiehanson/XMPPFramework/issues/101#issuecomment-13129364.
What code do you run when you enter background?
No code at all in AppDelegate's applicationDidEnterBackground, should I have something specific there? I just keep being connected to xmpp server and listening for messages.
I think you need to request permission to keep running while in the background, or else your app is suspended shortly after. This is Apple's documentation on background execution.
I have "Location" and "VoIP" in required background modes in Info.plist, I thought this is enough. Application runs for hours in background without any problem when there's uninterrupted access to data network. It's only when the network is temporary unavailable that it has problem reconnecting in background. Is it possible that once app is disconnected, it automatically stops to qualify being "VoIP" and is suspended by iOS?
Just did some digging, and it looks like you might also have to enable VOIP for the socket. There's a method -[GCDAsyncSocket enableBackgroundingOnSocketWithCaveat:] which does this but it doesn't look like it's used by the framework. You could try modifying XMPPStream to invoke that method and seeing if that makes a difference.
I'll try that, thanks. I also found that I may need to implement setKeepAliveTimeout and, possibly, use beginBackgroundTaskWithExpirationHandler. Will try all that later.
[GCDAsyncSocket enableBackgroundingOnSocketWithCaveat:] method is called by enableBackgroundingOnSocket which we are setting to true. Also i didn't find nay method with the name of beginBackgroundTaskWithExpirationHandler. setKeepAliveTimeout looks promising, will test tomorrow when i have a device.
Apple says the backgrounding of voip will work only when the socket is connected. Will dig the link and share.
On Wed, Feb 6, 2013 at 12:06 AM, misha2400 notifications@github.com wrote:
I'll try that, thanks. I also found that I may need to implement setKeepAliveTimeout and, possibly, use beginBackgroundTaskWithExpirationHandler. Will try all that later.
— Reply to this email directly or view it on GitHubhttps://github.com/robbiehanson/XMPPFramework/issues/101#issuecomment-13144113.
This is the most complete posting I found related to this.
http://stackoverflow.com/questions/5987495/how-to-maintain-voip-socket-connection-in-background
The other observation that I have is that when I turn on location updates, application seems to recover nicely from airplane mode, so I guess the problem is indeed related to app being suspended by OS.
Turn on location updates ? Like setting some property in plist or general location updates of iOS device from settings ?
I wonder when we are able to receive messages when the app is in background, why wont it reconnect automatically. I have tested my app, it was kept for almost 24 hours in background and there wasn't any internet disruption, it was working fine (able to receive messages). So the normal backgrounding is not an issue, the main issue is when the socket has been disconnected due to internet disconnection and the app is in background.
On Wed, Feb 6, 2013 at 12:27 AM, misha2400 notifications@github.com wrote:
The other observation that I have is that when I turn on location updates, application seems to recover nicely from airplane mode, so I guess the problem is indeed related to app being suspended by OS.
— Reply to this email directly or view it on GitHubhttps://github.com/robbiehanson/XMPPFramework/issues/101#issuecomment-13145218.
Here's how I understand it: when your app is in background mode, there's only certain events that can "wake it up" to do some processing - for VoIP this event would be some incoming traffic on the socket, for location app - some update in location. But when VoIP socket is closed, there's no way it can receive incoming traffic, so there's nothing that can "wake up" your app. If location update comes and wakes it up, it has a chance to restore the socket, that's why it recovers. Now, setKeepAliveTimeout supposedly also can wake up your app for, like, 10 sec, so if you manage to connect to server during that time and return from the handler - you're ok, if not - your app is suspended until you bring it to front manually. However beginBackgroundTaskWithExpirationHandler can, supposedly, increase that time interval to 10 minutes.
Thats correct because I tried but calling a function using NSTimer when the app was in background, and it didn't work. Will try with beginBackgroundTaskWithExpirationHandler once I have the device tomorrow.
On Wed, Feb 6, 2013 at 12:56 AM, misha2400 notifications@github.com wrote:
Here's how I understand it: when your app is in background mode, there's only certain events that can "wake it up" to do some processing - for VoIP this event would be some incoming traffic on the socket, for location app - some update in location. But when VoIP socket is closed, there's no way it can receive incoming traffic, so there's nothing that can "wake up" your app. If location update comes and wakes it up, it has a chance to restore the socket, that's why it recovers. Now, setKeepAliveTimeout supposedly also can wake up your app for, like, 10 sec, so if you manage to connect to server during that time and return from the handler - you're ok, if not - your app is suspended until you bring it to front manually. However beginBackgroundTaskWithExpirationHandler can, supposedly, increase that time interval to 10 minutes.
— Reply to this email directly or view it on GitHubhttps://github.com/robbiehanson/XMPPFramework/issues/101#issuecomment-13146803.
You know, another thing to try is to register for the connection-related notifications when entering background – the ones which XMPPReconnect needs.
Do you mean Reachability? Did that, don't get notified. I do get notified when data connection is lost, but never when it's restored, unless I bring the app back into foreground mode. I guess it's not meant for background mode at all.
You wont get anything via rechability, because you loose the callbacks when the reconnect module asks for them.
The bug in in the cgd async socket. I tried to debug it but i couldnt find anything.
Enviado do meu iPhone
No dia 05/02/2013, às 21:54, "misha2400" notifications@github.com escreveu:
Do you mean Reachability? Did that, don't get notified. I do get notified when data connection is lost, but never when it's restored, unless I bring the app back into foreground mode.
— Reply to this email directly or view it on GitHub.
Reachability doesn't work in background, so that cant be used.
On Wed, Feb 6, 2013 at 1:26 AM, jonasman notifications@github.com wrote:
You wont get anything via rechability, because you loose the callbacks when the reconnect module asks for them.
The bug in in the cgd async socket. I tried to debug it but i couldnt find anything.
Enviado do meu iPhone
No dia 05/02/2013, às 21:54, "misha2400" notifications@github.com escreveu:
Do you mean Reachability? Did that, don't get notified. I do get notified when data connection is lost, but never when it's restored, unless I bring the app back into foreground mode.
— Reply to this email directly or view it on GitHub.
— Reply to this email directly or view it on GitHubhttps://github.com/robbiehanson/XMPPFramework/issues/101#issuecomment-13148481.
Update: setKeepAliveTimeout helped, it connects me back to the server within 10 minutes. This is ok for me, if you want to connect immediately once data network is available, you will need to find another solution. That solution definitely exists, because I can see VoIP programs restore their connection in background within seconds after device comes back from Airplane Mode.
What do you have your timeout set to?
600. Actually I just looked at my logs and I see the interval between keepAlive handler calls varies and sometimes it's less than 10 minutes and sometimes it's several hours. So, I guess I still have no idea how it actually works, but it definitely keeps my client connected to server, which is all I care about.
So if we set the setKeepAliveTimeout, our client will be connected as soon as the internet is back and our app is in the background ? (if network is up within 10 mins)
And yes skype does connect in background, so does KIK messenger, so there has to be a solution for that. Thanks for the update though.
We had our QA firm look at the issue, it appears that when the user is changing connections we have the most issues.
Just an update, Skype uses push notification, so does KIK messenger to reconnect in background.
How we tested it ? Log into KIK messenger, kill it and send messages, you will still receive them. Skype uses push only for incoming voice calls. This basically leaves us with integrating push notification with openfire server if we want the auto reconnect functionality in background.
On Thu, Feb 14, 2013 at 4:17 AM, Bradford Toney notifications@github.comwrote:
We had our QA firm look at the issue, it appears that when the user is changing connections we have the most issues.
— Reply to this email directly or view it on GitHubhttps://github.com/robbiehanson/XMPPFramework/issues/101#issuecomment-13523036.
After a significant amount of digging, I think i've narrowed it down to a specific issue in CocoaAsyncSocket. https://github.com/robbiehanson/CocoaAsyncSocket/issues/131
yeah, i have been telling that the bug is for sure in the Asyncsocket. Now to find the solution it is not that easy
In my case i remade the module and adjusted it to my case. In short:
I added the rechability code from apple. And keep it running all the time instead of when there is a disconnect.
My logic: Try reconnect with timer when connection fails. After authenticated stop timer. When stream error, start reconnect. If wlan/3g changes, disconnect and reconnect. if no iternet, stop the reconnect timer until the internet comes back, when it comes back start the reconnect again.
With this logic change i was able to cover all of the reconnect problems and internet problems.
jonasman, how do you keep reachability running when the program is in the background mode? In my tests reachability doesn't wake your program up when network status changes.
I dont use background mode. I only use the background task ( beginBackgroundTaskWithExpirationHandler ). In this case it works. But I dont keep my app running forever, I just use it to complete tasks or other small things.
I am working on chat app using xmpp framework. I am facing connection issue on 3G network when network goes off or i put the device on airplane mode the application does not connect again it try to reconnect but connection never goes successful. I had tried all the options mention in the post buy unfortunately none of them is working in my case.
the application is working fine on WiFi network automatically reconnect on network failure, when network come again.
Kindly help me out to fix the reconnection issue on 3G network. Looking for kind help
Regards, Chauhan
So any luck to make XMPP stream connected to server, while application is in background. I got the app disconnected after 3 mins and no mechanism helped that can make the application alive other then calling it to foreground.
Regards, Tarun
Hi,
I have issues with XMPPReconnect - sometimes, when going from 3G to no-signal and back, XMPP didn't reconnect. I tried to simulate this using flight mode and I realized, that XMPPReconnect doesn't handle "no network reachable" event. Because XMPPStream doesn't use timeouts, it can happen, that this "no-signal" state is not detected and when network goes back to 3G, same socket is used. But at least our 3G network doesn't guarantee same IP address, so that socket is not working again. But because of no timeout, application is in state, that it looks like that is connected, but it is not.
I tried to implement experiment, using Apple reachability example and simply disconnect xmppSteam socket when reachability changed and both WLAN and WAN are not available. It fixes this issue and now XMPPReconnect works correctly.
Before I start to change XMPPReconnect I want to discuss, how this should be handled correctly. For example - should be also socket closed and created again with every reachability change? How is this handled now? Is socket closed automaitcally, when for example already connected on WiFi and new WiFi is connected?
Thanks,
Jindrich