ConnectionManager.coffee 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. define [], () ->
  2. class ConnectionManager
  3. constructor: (@ide, @$scope) ->
  4. @connected = false
  5. @$scope.connection =
  6. reconnecting: false
  7. # If we need to force everyone to reload the editor
  8. forced_disconnect: false
  9. @$scope.tryReconnectNow = () =>
  10. @tryReconnect()
  11. @$scope.$on "editor:change", () =>
  12. @lastUpdated = new Date()
  13. @ide.socket = io.connect null,
  14. reconnect: false
  15. "force new connection": true
  16. @ide.socket.on "connect", () =>
  17. @connected = true
  18. @ide.pushEvent("connected")
  19. @$scope.$apply () =>
  20. @$scope.connection.reconnecting = false
  21. if @$scope.state.loading
  22. @$scope.state.load_progress = 70
  23. setTimeout(() =>
  24. @joinProject()
  25. , 100)
  26. @ide.socket.on 'disconnect', () =>
  27. @connected = false
  28. @ide.pushEvent("disconnected")
  29. @$scope.$apply () =>
  30. @$scope.connection.reconnecting = false
  31. setTimeout(=>
  32. ga('send', 'event', 'editor-interaction', 'disconnect')
  33. , 2000)
  34. if !$scope.connection.forced_disconnect
  35. @startAutoReconnectCountdown()
  36. @ide.socket.on 'forceDisconnect', (message) =>
  37. @$scope.$apply () =>
  38. @$scope.permissions.write = false
  39. @$scope.connection.forced_disconnect = true
  40. @ide.socket.disconnect()
  41. @ide.showGenericMessageModal("Please Refresh", """
  42. We're performing maintenance on ShareLaTeX and you need to refresh the editor.
  43. Sorry for any inconvenience.
  44. The editor will refresh in automatically in 10 seconds.
  45. """)
  46. setTimeout () ->
  47. location.reload()
  48. , 10 * 1000
  49. joinProject: () ->
  50. @ide.socket.emit 'joinProject', {
  51. project_id: @ide.project_id
  52. }, (err, project, permissionsLevel, protocolVersion) =>
  53. if @$scope.protocolVersion? and @$scope.protocolVersion != protocolVersion
  54. location.reload(true)
  55. @$scope.$apply () =>
  56. @$scope.protocolVersion = protocolVersion
  57. @$scope.project = project
  58. @$scope.permissionsLevel = permissionsLevel
  59. @$scope.state.load_progress = 100
  60. @$scope.state.loading = false
  61. @$scope.$broadcast "project:joined"
  62. reconnectImmediately: () ->
  63. @disconnect()
  64. @tryReconnect()
  65. disconnect: () ->
  66. @ide.socket.disconnect()
  67. startAutoReconnectCountdown: () ->
  68. twoMinutes = 2 * 60 * 1000
  69. if @lastUpdated? and new Date() - @lastUpdated > twoMinutes
  70. # between 1 minute and 3 minutes
  71. countdown = 60 + Math.floor(Math.random() * 120)
  72. else
  73. countdown = 3 + Math.floor(Math.random() * 7)
  74. @$scope.$apply () =>
  75. @$scope.connection.reconnecting = false
  76. @$scope.connection.reconnection_countdown = countdown
  77. setTimeout(=>
  78. if !@connected
  79. @timeoutId = setTimeout (=> @decreaseCountdown()), 1000
  80. , 200)
  81. cancelReconnect: () ->
  82. clearTimeout @timeoutId if @timeoutId?
  83. decreaseCountdown: () ->
  84. return if !@$scope.connection.reconnection_countdown?
  85. @$scope.$apply () =>
  86. @$scope.connection.reconnection_countdown--
  87. if @$scope.connection.reconnection_countdown <= 0
  88. @$scope.$apply () =>
  89. @tryReconnect()
  90. else
  91. @timeoutId = setTimeout (=> @decreaseCountdown()), 1000
  92. tryReconnect: () ->
  93. @cancelReconnect()
  94. delete @$scope.connection.reconnection_countdown
  95. return if @connected
  96. @$scope.connection.reconnecting = true
  97. @ide.socket.socket.reconnect()
  98. setTimeout (=> @startAutoReconnectCountdown() if !@connected), 2000