1
0

PingServer.swift 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. //
  2. // PingServer.swift
  3. // Swifter
  4. //
  5. // Created by Brian Gerstle on 8/20/16.
  6. // Copyright © 2016 Damian Kołakowski. All rights reserved.
  7. //
  8. import Foundation
  9. // Server
  10. extension Swifter {
  11. class func pingServer() throws -> Swifter {
  12. let server = try Swifter()
  13. server.get("/ping") { _, request, responder in
  14. responder(TextResponse(200, "pong!"))
  15. }
  16. return server
  17. }
  18. }
  19. let defaultLocalhost = URL(string:"http://localhost:8080")!
  20. // Client
  21. extension URLSession {
  22. func pingTask(
  23. hostURL: URL = defaultLocalhost,
  24. completionHandler handler: @escaping (Data?, URLResponse?, Error?) -> Void
  25. ) -> URLSessionDataTask {
  26. return self.dataTask(with: hostURL.appendingPathComponent("/ping"), completionHandler: handler)
  27. }
  28. func retryPing(
  29. hostURL: URL = defaultLocalhost,
  30. timeout: Double = 2.0
  31. ) -> Bool {
  32. let semaphore = DispatchSemaphore(value: 0)
  33. self.signalIfPongReceived(semaphore, hostURL: hostURL)
  34. let timeoutDate = NSDate().addingTimeInterval(timeout)
  35. var timedOut = false
  36. while semaphore.wait(timeout: DispatchTime.now()) != DispatchTimeoutResult.timedOut {
  37. if NSDate().laterDate(timeoutDate as Date) != timeoutDate as Date {
  38. timedOut = true
  39. break
  40. }
  41. RunLoop.current.run(
  42. mode: RunLoopMode.commonModes,
  43. before: NSDate.distantFuture
  44. )
  45. }
  46. return timedOut
  47. }
  48. func signalIfPongReceived(_ semaphore: DispatchSemaphore, hostURL: URL) {
  49. pingTask(hostURL: hostURL) { data, response, error in
  50. if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
  51. semaphore.signal()
  52. } else {
  53. self.signalIfPongReceived(semaphore, hostURL: hostURL)
  54. }
  55. }.resume()
  56. }
  57. }