aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/app/assets/javascripts/action_cable/connection.coffee
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2016-02-23 16:41:26 +0100
committerDavid Heinemeier Hansson <david@loudthinking.com>2016-02-23 16:41:26 +0100
commitb2c2d32908beed678b087ec4ed735cc9ff87ad7a (patch)
tree33f62a5dcf5e1bc626cfeabb78c6bf49ddf9fd14 /actioncable/app/assets/javascripts/action_cable/connection.coffee
parent3b017856f72ac6711bfbbce2d6edd9c8b49923c1 (diff)
parentc889408e0d01f7d4fb061dbc53a2426bd359496c (diff)
downloadrails-b2c2d32908beed678b087ec4ed735cc9ff87ad7a.tar.gz
rails-b2c2d32908beed678b087ec4ed735cc9ff87ad7a.tar.bz2
rails-b2c2d32908beed678b087ec4ed735cc9ff87ad7a.zip
Merge pull request #23813 from lifo/faye-websocket
Improve Action Cable reconnection reliability
Diffstat (limited to 'actioncable/app/assets/javascripts/action_cable/connection.coffee')
-rw-r--r--actioncable/app/assets/javascripts/action_cable/connection.coffee26
1 files changed, 22 insertions, 4 deletions
diff --git a/actioncable/app/assets/javascripts/action_cable/connection.coffee b/actioncable/app/assets/javascripts/action_cable/connection.coffee
index fbd7dbd35b..ee888f567b 100644
--- a/actioncable/app/assets/javascripts/action_cable/connection.coffee
+++ b/actioncable/app/assets/javascripts/action_cable/connection.coffee
@@ -16,9 +16,12 @@ class ActionCable.Connection
false
open: =>
- if @webSocket and not @isState("closed")
+ if @isAlive()
+ ActionCable.log("Attemped to open WebSocket, but existing socket is #{@getState()}")
throw new Error("Existing connection must be closed before opening")
else
+ ActionCable.log("Opening WebSocket, current state is #{@getState()}")
+ @uninstallEventHandlers() if @webSocket?
@webSocket = new WebSocket(@consumer.url)
@installEventHandlers()
true
@@ -27,19 +30,26 @@ class ActionCable.Connection
@webSocket?.close()
reopen: ->
- if @isState("closed")
- @open()
- else
+ ActionCable.log("Reopening WebSocket, current state is #{@getState()}")
+ if @isAlive()
try
@close()
+ catch error
+ ActionCable.log("Failed to reopen WebSocket", error)
finally
+ ActionCable.log("Reopening WebSocket in #{@constructor.reopenDelay}ms")
setTimeout(@open, @constructor.reopenDelay)
+ else
+ @open()
isOpen: ->
@isState("open")
# Private
+ isAlive: ->
+ @webSocket? and not @isState("closing", "closed")
+
isState: (states...) ->
@getState() in states
@@ -53,6 +63,11 @@ class ActionCable.Connection
@webSocket["on#{eventName}"] = handler
return
+ uninstallEventHandlers: ->
+ for eventName of @events
+ @webSocket["on#{eventName}"] = ->
+ return
+
events:
message: (event) ->
{identifier, message, type} = JSON.parse(event.data)
@@ -66,13 +81,16 @@ class ActionCable.Connection
@consumer.subscriptions.notify(identifier, "received", message)
open: ->
+ ActionCable.log("WebSocket onopen event")
@disconnected = false
@consumer.subscriptions.reload()
close: ->
+ ActionCable.log("WebSocket onclose event")
@disconnect()
error: ->
+ ActionCable.log("WebSocket onerror event")
@disconnect()
disconnect: ->