-
Notifications
You must be signed in to change notification settings - Fork 12
/
XMPPPing.m
146 lines (115 loc) · 3.46 KB
/
XMPPPing.m
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
#import "XMPPPing.h"
#import "XMPP.h"
@implementation XMPPPing
- (id)initWithXMPPClient:(XMPPClient *)xmppClient delegate:(id)aDelegate
{
if(self = [super init])
{
delegate = aDelegate;
client = [xmppClient retain];
[client addDelegate:self];
pingIDs = [[NSMutableArray alloc] initWithCapacity:5];
}
return self;
}
- (void)dealloc
{
[client removeDelegate:self];
[client release];
[pingIDs release];
[super dealloc];
}
- (XMPPClient *)xmppClient
{
return client;
}
- (id)delegate
{
return delegate;
}
- (void)setDelegate:(id)newDelegate
{
delegate = newDelegate;
}
- (NSString *)generatePingID
{
// Generate unique ID for Ping packet
// It's important the ID be unique as the ID is the only thing that distinguishes a pong packet
CFUUIDRef uuid = CFUUIDCreate(NULL);
NSString *pingID = [NSMakeCollectable(CFUUIDCreateString(NULL, uuid)) autorelease];
CFRelease(uuid);
// Add ping ID to list so we'll recognize it when we get a response
[pingIDs addObject:pingID];
// In case we never get a response, we want to remove the ping ID eventually,
// or we risk an ever increasing pingIDs array.
[NSTimer scheduledTimerWithTimeInterval:30.0
target:self
selector:@selector(removePingID:)
userInfo:pingID
repeats:NO];
return pingID;
}
- (void)removePingID:(NSTimer *)aTimer
{
NSString *pingID = (NSString *)[aTimer userInfo];
[pingIDs removeObject:pingID];
}
- (void)sendPingToServer
{
NSString *pingID = [self generatePingID];
// Send ping packet
NSXMLElement *ping = [NSXMLElement elementWithName:@"ping" xmlns:@"urn:xmpp:ping"];
NSXMLElement *iq = [NSXMLElement elementWithName:@"iq"];
[iq addAttributeWithName:@"type" stringValue:@"get"];
[iq addAttributeWithName:@"id" stringValue:pingID];
[iq addChild:ping];
[client sendElement:iq];
}
- (void)sendPingToResource:(XMPPResource *)resource
{
NSString *pingID = [self generatePingID];
// Send ping packet
NSXMLElement *ping = [NSXMLElement elementWithName:@"ping" xmlns:@"urn:xmpp:ping"];
NSXMLElement *iq = [NSXMLElement elementWithName:@"iq"];
[iq addAttributeWithName:@"to" stringValue:[[resource jid] full]];
[iq addAttributeWithName:@"type" stringValue:@"get"];
[iq addAttributeWithName:@"id" stringValue:pingID];
[iq addChild:ping];
[client sendElement:iq];
}
- (void)xmppClient:(XMPPClient *)sender didReceiveIQ:(XMPPIQ *)iq
{
NSString *type = [[iq attributeForName:@"type"] stringValue];
if([type isEqualToString:@"result"] || [type isEqualToString:@"error"])
{
// Example:
// <iq from="deusty.com" to="[email protected]/work" id="abc123" type="result">
NSString *pingID = [iq elementID];
NSUInteger index = [pingIDs indexOfObject:pingID];
if(index != NSNotFound)
{
[pingIDs removeObjectAtIndex:index];
if([delegate respondsToSelector:@selector(xmppPing:didReceivePong:)])
{
[delegate xmppPing:self didReceivePong:iq];
}
}
}
else if([type isEqualToString:@"get"])
{
// Example:
// <iq from="deusty.com" to="[email protected]/work" id="zhq325" type="get">
// <ping xmlns="urn:xmpp:ping"/>
// </iq>
NSXMLElement *ping = [iq elementForName:@"ping" xmlns:@"urn:xmpp:ping"];
if(ping)
{
NSXMLElement *pong = [NSXMLElement elementWithName:@"iq"];
[pong addAttributeWithName:@"to" stringValue:[iq fromStr]];
[pong addAttributeWithName:@"type" stringValue:@"result"];
[pong addAttributeWithName:@"id" stringValue:[iq elementID]];
[client sendElement:pong];
}
}
}
@end