overleaf/services/web/public/coffee/ide/connection/ConnectionManager.coffee

131 lines
3.6 KiB
CoffeeScript
Raw Normal View History

define [], () ->
class ConnectionManager
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
2014-06-24 11:33:36 -04:00
@connected = false
@$scope.connection =
reconnecting: false
# If we need to force everyone to reload the editor
forced_disconnect: false
@$scope.tryReconnectNow = () =>
@tryReconnect()
2014-07-09 15:32:03 -04:00
@$scope.$on "editor:change", () =>
@lastUpdated = new Date()
2015-03-20 15:08:35 -04:00
@ide.socket = io.connect null,
reconnect: false
"force new connection": true
@ide.socket.on "connect", () =>
2014-06-24 11:33:36 -04:00
@connected = true
@ide.pushEvent("connected")
@$scope.$apply () =>
2014-06-24 11:33:36 -04:00
@$scope.connection.reconnecting = false
if @$scope.state.loading
2014-07-10 08:41:54 -04:00
@$scope.state.load_progress = 70
2014-06-24 11:33:36 -04:00
setTimeout(() =>
@joinProject()
, 100)
@ide.socket.on 'disconnect', () =>
@connected = false
@ide.pushEvent("disconnected")
@$scope.$apply () =>
@$scope.connection.reconnecting = false
setTimeout(=>
ga('send', 'event', 'editor-interaction', 'disconnect')
, 2000)
2014-06-24 11:33:36 -04:00
if !$scope.connection.forced_disconnect
@startAutoReconnectCountdown()
2014-06-24 11:33:36 -04:00
@ide.socket.on 'forceDisconnect', (message) =>
@$scope.$apply () =>
@$scope.permissions.write = false
2014-06-24 11:33:36 -04:00
@$scope.connection.forced_disconnect = true
2014-07-24 11:39:32 -04:00
@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
2014-06-24 11:33:36 -04:00
joinProject: () ->
@ide.socket.emit 'joinProject', {
project_id: @ide.project_id
}, (err, project, permissionsLevel, protocolVersion) =>
if @$scope.protocolVersion? and @$scope.protocolVersion != protocolVersion
location.reload(true)
2014-06-24 11:33:36 -04:00
@$scope.$apply () =>
@$scope.protocolVersion = protocolVersion
@$scope.project = project
@$scope.permissionsLevel = permissionsLevel
2014-06-24 11:33:36 -04:00
@$scope.state.load_progress = 100
@$scope.state.loading = false
@$scope.$broadcast "project:joined"
2014-06-24 10:31:44 -04:00
reconnectImmediately: () ->
@disconnect()
2014-06-24 11:33:36 -04:00
@tryReconnect()
2014-06-24 10:31:44 -04:00
disconnect: () ->
2014-06-24 11:33:36 -04:00
@ide.socket.disconnect()
startAutoReconnectCountdown: () ->
twoMinutes = 2 * 60 * 1000
2014-07-09 15:32:03 -04:00
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)
2014-06-24 11:33:36 -04:00
@$scope.$apply () =>
2014-07-02 11:41:29 -04:00
@$scope.connection.reconnecting = false
@$scope.connection.reconnection_countdown = countdown
2014-06-24 11:33:36 -04:00
setTimeout(=>
if !@connected
@timeoutId = setTimeout (=> @decreaseCountdown()), 1000
, 200)
cancelReconnect: () ->
clearTimeout @timeoutId if @timeoutId?
decreaseCountdown: () ->
return if !@$scope.connection.reconnection_countdown?
2014-06-24 11:33:36 -04:00
@$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
2014-07-17 08:44:50 -04:00
return if @connected
2014-06-24 11:33:36 -04:00
@$scope.connection.reconnecting = true
@ide.socket.socket.reconnect()
setTimeout (=> @startAutoReconnectCountdown() if !@connected), 2000
2014-06-24 11:33:36 -04:00