| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- define [], () ->
- ONEHOUR = 1000 * 60 * 60
- class ConnectionManager
- disconnectAfterMs: ONEHOUR * 24
- lastUserAction : new Date()
- constructor: (@ide, @$scope) ->
- if !io?
- console.error "Socket.io javascript not loaded. Please check that the real-time service is running and accessible."
- @ide.socket =
- on: () ->
- $scope.$apply () =>
- @$scope.state.error = "Could not connect to websocket server :("
- return
- setInterval(() =>
- @disconnectIfInactive()
- , ONEHOUR)
- @userIsLeavingPage = false
- window.addEventListener 'beforeunload', =>
- @userIsLeavingPage = true
- return # Don't return true or it will show a pop up
- @connected = false
- @userIsInactive = false
-
- @$scope.connection =
- reconnecting: false
- # If we need to force everyone to reload the editor
- forced_disconnect: false
- inactive_disconnect: false
- @$scope.tryReconnectNow = () =>
- @tryReconnect()
- @$scope.$on 'cursor:editor:update', () =>
- @lastUserAction = new Date()
- if !@connected
- @tryReconnect()
- document.querySelector('body').addEventListener 'click', (e) =>
- if !@connected and e.target.id != 'try-reconnect-now-button'
- @tryReconnect()
- @ide.socket = io.connect null,
- reconnect: false
- 'connect timeout': 30 * 1000
- "force new connection": true
- @ide.socket.on "connect", () =>
- sl_console.log "[socket.io connect] Connected"
- @connected = true
- @ide.pushEvent("connected")
- @$scope.$apply () =>
- @$scope.connection.reconnecting = false
- @$scope.connection.inactive_disconnect = false
- if @$scope.state.loading
- @$scope.state.load_progress = 70
- setTimeout(() =>
- @joinProject()
- , 100)
- @ide.socket.on "connect_failed", () =>
- @connected = false
- $scope.$apply () =>
- @$scope.state.error = "Unable to connect, please view the <u><a href='http://sharelatex.tenderapp.com/help/kb/latex-editor/editor-connection-problems'>connection problems guide</a></u> to fix the issue."
- @ide.socket.on 'disconnect', () =>
- sl_console.log "[socket.io disconnect] Disconnected"
- @connected = false
- @ide.pushEvent("disconnected")
- @$scope.$apply () =>
- @$scope.connection.reconnecting = false
- if !$scope.connection.forced_disconnect and !@userIsInactive
- @startAutoReconnectCountdown()
- @ide.socket.on 'forceDisconnect', (message) =>
- @$scope.$apply () =>
- @$scope.permissions.write = false
- @$scope.connection.forced_disconnect = true
- @ide.socket.disconnect()
- @ide.showGenericMessageModal("Please Refresh", """
- We're performing maintenance on ShareLaTeX and you need to refresh the editor.
- Sorry for any inconvenience.
- The editor will refresh in automatically in 10 seconds.
- """)
- setTimeout () ->
- location.reload()
- , 10 * 1000
-
- joinProject: () ->
- sl_console.log "[joinProject] joining..."
- @ide.socket.emit 'joinProject', {
- project_id: @ide.project_id
- }, (err, project, permissionsLevel, protocolVersion) =>
- if err?
- if err.message == "not authorized"
- window.location = "/login?redir=#{encodeURI(window.location.pathname)}"
- else
- @ide.socket.disconnect()
- @ide.showGenericMessageModal("Something went wrong connecting", """
- Something went wrong connecting to your project. Please refresh is this continues to happen.
- """)
- return
- if @$scope.protocolVersion? and @$scope.protocolVersion != protocolVersion
- location.reload(true)
- @$scope.$apply () =>
- @$scope.protocolVersion = protocolVersion
- @$scope.project = project
- @$scope.permissionsLevel = permissionsLevel
- @$scope.state.load_progress = 100
- @$scope.state.loading = false
- @$scope.$broadcast "project:joined"
- reconnectImmediately: () ->
- @disconnect()
- @tryReconnect()
- disconnect: () ->
- @ide.socket.disconnect()
- startAutoReconnectCountdown: () ->
- twoMinutes = 2 * 60 * 1000
- if @lastUpdated? and new Date() - @lastUpdated > twoMinutes
- # between 1 minute and 3 minutes
- countdown = 60 + Math.floor(Math.random() * 120)
- else
- countdown = 3 + Math.floor(Math.random() * 7)
- if @userIsLeavingPage #user will have pressed refresh or back etc
- return
- @$scope.$apply () =>
- @$scope.connection.reconnecting = false
- @$scope.connection.reconnection_countdown = countdown
- setTimeout(=>
- if !@connected
- @timeoutId = setTimeout (=> @decreaseCountdown()), 1000
- , 200)
- cancelReconnect: () ->
- clearTimeout @timeoutId if @timeoutId?
-
- decreaseCountdown: () ->
- return if !@$scope.connection.reconnection_countdown?
- @$scope.$apply () =>
- @$scope.connection.reconnection_countdown--
- if @$scope.connection.reconnection_countdown <= 0
- @$scope.$apply () =>
- @tryReconnect()
- else
- @timeoutId = setTimeout (=> @decreaseCountdown()), 1000
- tryReconnect: () ->
- @cancelReconnect()
- delete @$scope.connection.reconnection_countdown
- return if @connected
- @$scope.connection.reconnecting = true
- @ide.socket.socket.reconnect()
- setTimeout (=> @startAutoReconnectCountdown() if !@connected), 2000
- disconnectIfInactive: ()->
- @userIsInactive = (new Date() - @lastUserAction) > @disconnectAfterMs
- if @userIsInactive and @connected
- @disconnect()
- @$scope.$apply () =>
- @$scope.connection.inactive_disconnect = true
|