ConnectionManager.coffee 3.6 KB

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