XMPPReconnect.h
7.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import "XMPPModule.h"
#define _XMPP_RECONNECT_H
#define DEFAULT_XMPP_RECONNECT_DELAY 2.0
#define DEFAULT_XMPP_RECONNECT_TIMER_INTERVAL 20.0
@protocol XMPPReconnectDelegate;
/**
* XMPPReconnect handles automatically reconnecting to the xmpp server due to accidental disconnections.
* That is, a disconnection that is not the result of calling disconnect on the xmpp stream.
*
* Accidental disconnections may happen for a variety of reasons.
* The most common are general connectivity issues such as disconnection from a WiFi access point.
*
* However, there are several of issues that occasionaly occur.
* There are some routers on the market that disconnect TCP streams after a period of inactivity.
* In addition to this, there have been iPhone revisions where the OS networking stack would pull the same crap.
* These issue have been largely overcome due to the keepalive implementation in XMPPStream.
*
* Regardless of how the disconnect happens, the XMPPReconnect class can help to automatically re-establish
* the xmpp stream so as to have minimum impact on the user (and hopefully they don't even notice).
*
* Once a stream has been opened and authenticated, this class will detect any accidental disconnections.
* If one occurs, an attempt will be made to automatically reconnect after a short delay.
* This delay is configurable via the reconnectDelay property.
* At the same time the class will begin monitoring the network for reachability changes.
* When the reachability of the xmpp host has changed, a reconnect may be tried again.
* In addition to all this, a timer may optionally be used to attempt a reconnect periodically.
* The timer is started if the initial reconnect fails.
* This reconnect timer is fully configurable (may be enabled/disabled, and it's timeout may be changed).
*
* In all cases, prior to attempting a reconnect,
* this class will invoke the shouldAttemptAutoReconnect delegate method.
* The delegate may use this opportunity to optionally decline the auto reconnect attempt.
*
* Auto reconnect may be disabled at any time via the autoReconnect property.
*
* Note that auto reconnect will only occur for a stream that has been opened and authenticated.
* So it will do nothing, for example, if there is no internet connectivity when your application
* first launches, and the xmpp stream is unable to connect to the host.
* In cases such as this it may be desireable to start monitoring the network for reachability changes.
* This way when internet connectivity is restored, one can immediately connect the xmpp stream.
* This is possible via the manualStart method,
* which will trigger the class into action just as if an accidental disconnect occurred.
**/
@interface XMPPReconnect : XMPPModule
{
Byte flags;
Byte config;
NSTimeInterval reconnectDelay;
dispatch_source_t reconnectTimer;
NSTimeInterval reconnectTimerInterval;
SCNetworkReachabilityRef reachability;
int reconnectTicket;
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
SCNetworkConnectionFlags previousReachabilityFlags;
#else
SCNetworkReachabilityFlags previousReachabilityFlags;
#endif
}
/**
* Whether auto reconnect is enabled or disabled.
*
* The default value is YES (enabled).
*
* Note: Altering this property will only affect future accidental disconnections.
* For example, if autoReconnect was true, and you disable this property after an accidental disconnection,
* this will not stop the current reconnect process.
* In order to stop a current reconnect process use the stop method.
*
* Similarly, if autoReconnect was false, and you enable this property after an accidental disconnection,
* this will not start a reconnect process.
* In order to start a reconnect process use the manualStart method.
**/
@property (nonatomic, assign) BOOL autoReconnect;
/**
* When the accidental disconnection first happens,
* a short delay may be used before attempting the reconnection.
*
* The default value is DEFAULT_XMPP_RECONNECT_DELAY (defined at the top of this file).
*
* To disable this feature, set the value to zero.
*
* Note: NSTimeInterval is a double that specifies the time in seconds.
**/
@property (nonatomic, assign) NSTimeInterval reconnectDelay;
/**
* A reconnect timer may optionally be used to attempt a reconnect periodically.
* The timer will be started after the initial reconnect delay.
*
* The default value is DEFAULT_XMPP_RECONNECT_TIMER_INTERVAL (defined at the top of this file).
*
* To disable this feature, set the value to zero.
*
* Note: NSTimeInterval is a double that specifies the time in seconds.
**/
@property (nonatomic, assign) NSTimeInterval reconnectTimerInterval;
/**
* Whether you want to reconnect using the legacy method -[XMPPStream oldSchoolSecureConnectWithTimeout:error:]
* instead of the standard -[XMPPStream connect:].
*
* If you initially connect using -oldSchoolSecureConnectWithTimeout:error:, set this to YES to reconnect the same way.
*
* The default value is NO (disabled).
*/
@property (nonatomic, assign) BOOL usesOldSchoolSecureConnect;
/**
* As opposed to using autoReconnect, this method may be used to manually start the reconnect process.
* This may be useful, for example, if one needs network monitoring in order to setup the inital xmpp connection.
* Or if one wants autoReconnect but only in very limited situations which they prefer to control manually.
*
* After invoking this method one can expect the class to act as if an accidental disconnect just occurred.
* That is, a reconnect attempt will be tried after reconnectDelay seconds,
* and the class will begin monitoring the network for changes in reachability to the xmpp host.
*
* A manual start of the reconnect process will effectively end once the xmpp stream has been opened.
* That is, if you invoke manualStart and the xmpp stream is later opened,
* then future disconnections will not result in an auto reconnect process (unless the autoReconnect property applies).
*
* This method does nothing if the xmpp stream is not disconnected.
**/
- (void)manualStart;
/**
* Stops the current reconnect process.
*
* This method will stop the current reconnect process regardless of whether the
* reconnect process was started due to the autoReconnect property or due to a call to manualStart.
*
* Stopping the reconnect process does NOT prevent future auto reconnects if the property is enabled.
* That is, if the autoReconnect property is still enabled, and the xmpp stream is later opened, authenticated and
* accidentally disconnected, this class will still attempt an automatic reconnect.
*
* Stopping the reconnect process does NOT prevent future calls to manualStart from working.
*
* It only stops the CURRENT reconnect process.
**/
- (void)stop;
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@protocol XMPPReconnectDelegate
@optional
/**
* This method may be used to fine tune when we
* should and should not attempt an auto reconnect.
*
* For example, if on the iPhone, one may want to prevent auto reconnect when WiFi is not available.
**/
#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
- (void)xmppReconnect:(XMPPReconnect *)sender didDetectAccidentalDisconnect:(SCNetworkConnectionFlags)connectionFlags;
- (BOOL)xmppReconnect:(XMPPReconnect *)sender shouldAttemptAutoReconnect:(SCNetworkConnectionFlags)connectionFlags;
#else
- (void)xmppReconnect:(XMPPReconnect *)sender didDetectAccidentalDisconnect:(SCNetworkReachabilityFlags)connectionFlags;
- (BOOL)xmppReconnect:(XMPPReconnect *)sender shouldAttemptAutoReconnect:(SCNetworkReachabilityFlags)reachabilityFlags;
#endif
@end