@@ -53,7 +53,7 @@ public class Client: WebSocketDelegate {
5353 public var teamProfileEventsDelegate : TeamProfileEventsDelegate ?
5454
5555 internal var token = " SLACK_AUTH_TOKEN "
56-
56+
5757 public func setAuthToken( token: String ) {
5858 self . token = token
5959 }
@@ -63,15 +63,25 @@ public class Client: WebSocketDelegate {
6363 }
6464
6565 internal var webSocket : WebSocket ?
66+ internal let api = NetworkInterface ( )
6667 private var dispatcher : EventDispatcher ?
6768
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 ?
6976
7077 required public init ( apiToken: String ) {
7178 self . token = apiToken
7279 }
7380
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
7585 dispatcher = EventDispatcher ( client: self )
7686 webAPI. rtmStart ( success: {
7787 ( response) -> Void in
@@ -85,6 +95,10 @@ public class Client: WebSocketDelegate {
8595 } , failure: nil )
8696 }
8797
98+ public func disconnect( ) {
99+ webSocket? . disconnect ( )
100+ }
101+
88102 //MARK: - Message send
89103 public func sendMessage( message: String , channelID: String ) {
90104 if ( connected) {
@@ -97,7 +111,7 @@ public class Client: WebSocketDelegate {
97111
98112 private func formatMessageToSlackJsonString( message: ( msg: String , channel: String ) ) -> NSData ? {
99113 let json : [ String : AnyObject ] = [
100- " id " : NSDate ( ) . timeIntervalSince1970 ,
114+ " id " : NSDate ( ) . slackTimestamp ( ) ,
101115 " type " : " message " ,
102116 " channel " : message. channel,
103117 " text " : message. msg. slackFormatEscaping ( )
@@ -121,6 +135,52 @@ public class Client: WebSocketDelegate {
121135 sentMessages [ ts!. stringValue] = Message ( message: message)
122136 }
123137
138+ //MARK: - RTM Ping
139+ private func pingRTMServerAtInterval( interval: NSTimeInterval ) {
140+ let delay = dispatch_time ( DISPATCH_TIME_NOW, Int64 ( interval * Double( NSEC_PER_SEC) ) )
141+ dispatch_after ( delay, pingPongQueue, {
142+ if self . connected && self . timeoutCheck ( ) {
143+ self . sendRTMPing ( )
144+ self . pingRTMServerAtInterval ( interval)
145+ } else {
146+ self . disconnect ( )
147+ }
148+ } )
149+ }
150+
151+ private func sendRTMPing( ) {
152+ if connected {
153+ let json : [ String : AnyObject ] = [
154+ " id " : NSDate ( ) . slackTimestamp ( ) ,
155+ " type " : " ping " ,
156+ ]
157+ do {
158+ let data = try NSJSONSerialization . dataWithJSONObject ( json, options: NSJSONWritingOptions . PrettyPrinted)
159+ let string = NSString ( data: data, encoding: NSUTF8StringEncoding)
160+ if let writePing = string as? String {
161+ ping = json [ " id " ] as? Double
162+ webSocket? . writeString ( writePing)
163+ }
164+ }
165+ catch _ {
166+
167+ }
168+ }
169+ }
170+
171+ private func timeoutCheck( ) -> Bool {
172+ if let pong = pong, ping = ping, timeout = timeout {
173+ if pong - ping < timeout {
174+ return true
175+ } else {
176+ return false
177+ }
178+ // Ping-pong or timeout not configured
179+ } else {
180+ return true
181+ }
182+ }
183+
124184 //MARK: - Client setup
125185 internal func initialSetup( json: [ String: AnyObject] ) {
126186 team = Team ( team: json [ " team " ] as? [ String : AnyObject ] )
@@ -207,14 +267,21 @@ public class Client: WebSocketDelegate {
207267 }
208268
209269 // MARK: - WebSocketDelegate
210- public func websocketDidConnect( socket: WebSocket ) { }
270+ public func websocketDidConnect( socket: WebSocket) {
271+ if let pingInterval = pingInterval {
272+ pingRTMServerAtInterval ( pingInterval)
273+ }
274+ }
211275
212276 public func websocketDidDisconnect( socket: WebSocket, error: NSError? ) {
213277 connected = false
214278 authenticated = false
215279 webSocket = nil
216- if let delegate = slackEventsDelegate {
217- delegate. clientDisconnected ( )
280+ dispatcher = nil
281+ authenticatedUser = nil
282+ slackEventsDelegate? . clientDisconnected ( )
283+ if reconnect == true {
284+ connect ( pingInterval: pingInterval, timeout: timeout, reconnect: reconnect)
218285 }
219286 }
220287
@@ -223,7 +290,9 @@ public class Client: WebSocketDelegate {
223290 return
224291 }
225292 do {
226- try dispatcher? . dispatch ( NSJSONSerialization . JSONObjectWithData ( data, options: NSJSONReadingOptions . AllowFragments) as! [ String : AnyObject ] )
293+ if let json = try NSJSONSerialization . JSONObjectWithData ( data, options: NSJSONReadingOptions . AllowFragments) as? [ String : AnyObject ] {
294+ dispatcher? . dispatch ( json)
295+ }
227296 }
228297 catch _ {
229298
0 commit comments