@@ -53,7 +53,7 @@ public class Client: WebSocketDelegate {
53
53
public var teamProfileEventsDelegate : TeamProfileEventsDelegate ?
54
54
55
55
internal var token = " SLACK_AUTH_TOKEN "
56
-
56
+
57
57
public func setAuthToken( token: String ) {
58
58
self . token = token
59
59
}
@@ -63,15 +63,25 @@ public class Client: WebSocketDelegate {
63
63
}
64
64
65
65
internal var webSocket : WebSocket ?
66
+ internal let api = NetworkInterface ( )
66
67
private var dispatcher : EventDispatcher ?
67
68
68
- internal let api = NetworkInterface ( )
69
+ private let pingPongQueue = dispatch_queue_create ( " com.launchsoft.SlackKit " , DISPATCH_QUEUE_SERIAL)
70
+ internal var ping : Double ?
71
+ internal var pong : Double ?
72
+
73
+ internal var pingInterval : NSTimeInterval ?
74
+ internal var timeout : NSTimeInterval ?
75
+ internal var reconnect : Bool ?
69
76
70
77
required public init ( apiToken: String ) {
71
78
self . token = apiToken
72
79
}
73
80
74
- public func connect( ) {
81
+ public func connect( pingInterval pingInterval: NSTimeInterval ? = nil , timeout: NSTimeInterval ? = nil , reconnect: Bool ? = nil ) {
82
+ self . pingInterval = pingInterval
83
+ self . timeout = timeout
84
+ self . reconnect = reconnect
75
85
dispatcher = EventDispatcher ( client: self )
76
86
webAPI. rtmStart ( success: {
77
87
( response) -> Void in
@@ -85,19 +95,24 @@ public class Client: WebSocketDelegate {
85
95
} , failure: nil )
86
96
}
87
97
98
+ public func disconnect( ) {
99
+ webSocket? . disconnect ( )
100
+ }
101
+
88
102
//MARK: - Message send
89
103
public func sendMessage( message: String , channelID: String ) {
90
104
if ( connected) {
91
105
if let data = formatMessageToSlackJsonString ( msg: message, channel: channelID) {
92
- let string = NSString ( data: data, encoding: NSUTF8StringEncoding)
93
- webSocket? . writeString ( string as! String )
106
+ if let string = NSString ( data: data, encoding: NSUTF8StringEncoding) as? String {
107
+ webSocket? . writeString ( string)
108
+ }
94
109
}
95
110
}
96
111
}
97
112
98
113
private func formatMessageToSlackJsonString( message: ( msg: String , channel: String ) ) -> NSData ? {
99
114
let json : [ String : AnyObject ] = [
100
- " id " : NSDate ( ) . timeIntervalSince1970 ,
115
+ " id " : NSDate ( ) . slackTimestamp ( ) ,
101
116
" type " : " message " ,
102
117
" channel " : message. channel,
103
118
" text " : message. msg. slackFormatEscaping ( )
@@ -121,6 +136,52 @@ public class Client: WebSocketDelegate {
121
136
sentMessages [ ts!. stringValue] = Message ( message: message)
122
137
}
123
138
139
+ //MARK: - RTM Ping
140
+ private func pingRTMServerAtInterval( interval: NSTimeInterval ) {
141
+ let delay = dispatch_time ( DISPATCH_TIME_NOW, Int64 ( interval * Double( NSEC_PER_SEC) ) )
142
+ dispatch_after ( delay, pingPongQueue, {
143
+ if self . connected && self . timeoutCheck ( ) {
144
+ self . sendRTMPing ( )
145
+ self . pingRTMServerAtInterval ( interval)
146
+ } else {
147
+ self . disconnect ( )
148
+ }
149
+ } )
150
+ }
151
+
152
+ private func sendRTMPing( ) {
153
+ if connected {
154
+ let json : [ String : AnyObject ] = [
155
+ " id " : NSDate ( ) . slackTimestamp ( ) ,
156
+ " type " : " ping " ,
157
+ ]
158
+ do {
159
+ let data = try NSJSONSerialization . dataWithJSONObject ( json, options: NSJSONWritingOptions . PrettyPrinted)
160
+ let string = NSString ( data: data, encoding: NSUTF8StringEncoding)
161
+ if let writePing = string as? String {
162
+ ping = json [ " id " ] as? Double
163
+ webSocket? . writeString ( writePing)
164
+ }
165
+ }
166
+ catch _ {
167
+
168
+ }
169
+ }
170
+ }
171
+
172
+ private func timeoutCheck( ) -> Bool {
173
+ if let pong = pong, ping = ping, timeout = timeout {
174
+ if pong - ping < timeout {
175
+ return true
176
+ } else {
177
+ return false
178
+ }
179
+ // Ping-pong or timeout not configured
180
+ } else {
181
+ return true
182
+ }
183
+ }
184
+
124
185
//MARK: - Client setup
125
186
internal func initialSetup( json: [ String: AnyObject] ) {
126
187
team = Team ( team: json [ " team " ] as? [ String : AnyObject ] )
@@ -207,14 +268,21 @@ public class Client: WebSocketDelegate {
207
268
}
208
269
209
270
// MARK: - WebSocketDelegate
210
- public func websocketDidConnect( socket: WebSocket ) { }
271
+ public func websocketDidConnect( socket: WebSocket) {
272
+ if let pingInterval = pingInterval {
273
+ pingRTMServerAtInterval ( pingInterval)
274
+ }
275
+ }
211
276
212
277
public func websocketDidDisconnect( socket: WebSocket, error: NSError? ) {
213
278
connected = false
214
279
authenticated = false
215
280
webSocket = nil
216
- if let delegate = slackEventsDelegate {
217
- delegate. clientDisconnected ( )
281
+ dispatcher = nil
282
+ authenticatedUser = nil
283
+ slackEventsDelegate? . clientDisconnected ( )
284
+ if reconnect == true {
285
+ connect ( pingInterval: pingInterval, timeout: timeout, reconnect: reconnect)
218
286
}
219
287
}
220
288
@@ -223,7 +291,9 @@ public class Client: WebSocketDelegate {
223
291
return
224
292
}
225
293
do {
226
- try dispatcher? . dispatch ( NSJSONSerialization . JSONObjectWithData ( data, options: NSJSONReadingOptions . AllowFragments) as! [ String : AnyObject ] )
294
+ if let json = try NSJSONSerialization . JSONObjectWithData ( data, options: NSJSONReadingOptions . AllowFragments) as? [ String : AnyObject ] {
295
+ dispatcher? . dispatch ( json)
296
+ }
227
297
}
228
298
catch _ {
229
299
0 commit comments