 				'connect timeout': 30 * 1000
 				"force new connection": true
 
+			# The "connect" event is the first event we get back. It only
+			# indicates that the websocket is connected, we still need to
+			# pass authentication to join a project.
+
 			@ide.socket.on "connect", () =>
 				sl_console.log "[socket.io connect] Connected"
+
+			# The next event we should get is an authentication response
+			# from the server, either "connectionAccepted" or
+			# "connectionRejected".
+
+			@ide.socket.on 'connectionAccepted', (message) =>
+				sl_console.log "[socket.io connectionAccepted] allowed to connect"
 				@connected = true
 				@gracefullyReconnecting = false
 				@ide.pushEvent("connected")

			@reconnectGracefullyStarted = null
			# Clear cookie so we don't go to the same backend server
			$.cookie("SERVERID", "", { expires: -1, path: "/" })
			@reconnectImmediately()
				setTimeout () ->
					location.reload()
				, 10 * 1000

			@ide.socket.on "reconnectGracefully", () =>
				sl_console.log "Reconnect gracefully"
				@reconnectGracefully()

		# Error reporting, which can reload the page if appropriate

		reportConnectionError: (err) ->
			sl_console.log "[socket.io] reporting connection error"
			if err?.message == "not authorized" or err?.message == "invalid session"
				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.
				""")

		joinProject: () ->
			sl_console.log "[joinProject] joining..."
			# Note: if the "joinProject" message doesn't reach the server
			# (e.g. if we are in a disconnected state at this point) the
			# callback will never be executed
			@ide.socket.emit 'joinProject', {
				project_id: @ide.project_id
			}, (err, project, permissionsLevel, protocolVersion) =>
				if err?
					return @reportConnectionError(err)

				if @$scope.protocolVersion? and @$scope.protocolVersion != protocolVersion
					location.reload(true)
