@@ -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,19 +95,24 @@ 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) {
91105 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+ }
94109 }
95110 }
96111 }
97112
98113 private func formatMessageToSlackJsonString( message: ( msg: String , channel: String ) ) -> NSData ? {
99114 let json : [ String : AnyObject ] = [
100- " id " : NSDate ( ) . timeIntervalSince1970 ,
115+ " id " : NSDate ( ) . slackTimestamp ( ) ,
101116 " type " : " message " ,
102117 " channel " : message. channel,
103118 " text " : message. msg. slackFormatEscaping ( )
@@ -121,6 +136,52 @@ public class Client: WebSocketDelegate {
121136 sentMessages [ ts!. stringValue] = Message ( message: message)
122137 }
123138
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+
124185 //MARK: - Client setup
125186 internal func initialSetup( json: [ String: AnyObject] ) {
126187 team = Team ( team: json [ " team " ] as? [ String : AnyObject ] )
@@ -207,14 +268,21 @@ public class Client: WebSocketDelegate {
207268 }
208269
209270 // MARK: - WebSocketDelegate
210- public func websocketDidConnect( socket: WebSocket ) { }
271+ public func websocketDidConnect( socket: WebSocket) {
272+ if let pingInterval = pingInterval {
273+ pingRTMServerAtInterval ( pingInterval)
274+ }
275+ }
211276
212277 public func websocketDidDisconnect( socket: WebSocket, error: NSError? ) {
213278 connected = false
214279 authenticated = false
215280 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)
218286 }
219287 }
220288
@@ -223,7 +291,9 @@ public class Client: WebSocketDelegate {
223291 return
224292 }
225293 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+ }
227297 }
228298 catch _ {
229299
0 commit comments