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. import Swifter
  10. // Server
  11. extension HttpServer {
  12. class func pingServer() -> HttpServer {
  13. let server = HttpServer()
  14. server.GET["/ping"] = { request in
  15. return HttpResponse.ok(.text("pong!"))
  16. }
  17. return server
  18. }
  19. }
  20. let defaultLocalhost = URL(string:"http://localhost:8080")!
  21. // Client
  22. extension URLSession {
  23. func pingTask(
  24. hostURL: URL = defaultLocalhost,
  25. completionHandler handler: @escaping (Data?, URLResponse?, Error?) -> Void
  26. ) -> URLSessionDataTask {
  27. return self.dataTask(with: hostURL.appendingPathComponent("/ping"), completionHandler: handler)
  28. }
  29. func retryPing(
  30. hostURL: URL = defaultLocalhost,
  31. timeout: Double = 2.0
  32. ) -> Bool {
  33. let semaphore = DispatchSemaphore(value: 0)
  34. self.signalIfPongReceived(semaphore, hostURL: hostURL)
  35. let timeoutDate = NSDate().addingTimeInterval(timeout)
  36. var timedOut = false
  37. while semaphore.wait(timeout: DispatchTime.now()) != DispatchTimeoutResult.timedOut {
  38. if NSDate().laterDate(timeoutDate as Date) != timeoutDate as Date {
  39. timedOut = true
  40. break
  41. }
  42. RunLoop.current.run(
  43. mode: RunLoopMode.commonModes,
  44. before: NSDate.distantFuture
  45. )
  46. }
  47. return timedOut
  48. }
  49. func signalIfPongReceived(_ semaphore: DispatchSemaphore, hostURL: URL) {
  50. pingTask(hostURL: hostURL) { data, response, error in
  51. if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
  52. semaphore.signal()
  53. } else {
  54. self.signalIfPongReceived(semaphore, hostURL: hostURL)
  55. }
  56. }.resume()
  57. }
  58. }