aboutsummaryrefslogtreecommitdiffstats
path: root/lib/assets
diff options
context:
space:
mode:
authorJavan Makhmali <javan@javan.us>2015-06-25 13:52:47 -0400
committerJavan Makhmali <javan@javan.us>2015-06-25 13:57:40 -0400
commitc846f43d46908750020710b4e9437f9395fb9594 (patch)
tree2f84981735bd0f41b128179dd0680df5d0d9e06c /lib/assets
parentd9d7371c568fe99ef460202ebe7217bfed050e88 (diff)
downloadrails-c846f43d46908750020710b4e9437f9395fb9594.tar.gz
rails-c846f43d46908750020710b4e9437f9395fb9594.tar.bz2
rails-c846f43d46908750020710b4e9437f9395fb9594.zip
Extract connection monitoring and rewrite as a subscriber
Diffstat (limited to 'lib/assets')
-rw-r--r--lib/assets/javascripts/cable.js.coffee2
-rw-r--r--lib/assets/javascripts/cable/connection.js.coffee94
-rw-r--r--lib/assets/javascripts/cable/connection_monitor.js.coffee41
-rw-r--r--lib/assets/javascripts/cable/subscriber_manager.js.coffee1
4 files changed, 66 insertions, 72 deletions
diff --git a/lib/assets/javascripts/cable.js.coffee b/lib/assets/javascripts/cable.js.coffee
index 86e08e15c0..0f1d7c8773 100644
--- a/lib/assets/javascripts/cable.js.coffee
+++ b/lib/assets/javascripts/cable.js.coffee
@@ -4,6 +4,8 @@
#= require cable/channel
class @Cable
+ @PING_IDENTIFIER: "_ping"
+
constructor: (@url) ->
@subscribers = new Cable.SubscriberManager this
@connection = new Cable.Connection this
diff --git a/lib/assets/javascripts/cable/connection.js.coffee b/lib/assets/javascripts/cable/connection.js.coffee
index e987c227c6..096dd519f7 100644
--- a/lib/assets/javascripts/cable/connection.js.coffee
+++ b/lib/assets/javascripts/cable/connection.js.coffee
@@ -1,10 +1,8 @@
-class Cable.Connection
- MAX_CONNECTION_INTERVAL: 5 * 1000
- PING_STALE_INTERVAL: 8
+#= require cable/connection_monitor
+class Cable.Connection
constructor: (@cable) ->
- @resetPingTime()
- @resetConnectionAttemptsCount()
+ new Cable.ConnectionMonitor @cable
@connect()
send: (data) ->
@@ -15,88 +13,40 @@ class Cable.Connection
false
connect: ->
- @websocket = @createWebSocket()
+ @removeWebsocket()
+ @createWebSocket()
createWebSocket: ->
- ws = new WebSocket(@cable.url)
- ws.onmessage = @onMessage
- ws.onopen = @onConnect
- ws.onclose = @onClose
- ws.onerror = @onError
- ws
+ @websocket = new WebSocket(@cable.url)
+ @websocket.onmessage = @onMessage
+ @websocket.onopen = @onConnect
+ @websocket.onclose = @onClose
+ @websocket.onerror = @onError
+ @websocket
+
+ removeWebsocket: ->
+ if @websocket?
+ @websocket.onclose = -> # no-op
+ @websocket.onerror = -> # no-op
+ @websocket.close()
+ @websocket = null
onMessage: (message) =>
data = JSON.parse message.data
-
- if data.identifier is '_ping'
- @pingReceived(data.message)
- else
- @cable.subscribers.notify(data.identifier, "received", data.message)
+ @cable.subscribers.notify(data.identifier, "received", data.message)
onConnect: =>
- @startWaitingForPing()
- @resetConnectionAttemptsCount()
@cable.subscribers.reload()
onClose: =>
- @reconnect()
+ @disconnect()
onError: =>
- @reconnect()
+ @disconnect()
isConnected: ->
@websocket?.readyState is 1
disconnect: ->
- @removeExistingConnection()
- @resetPingTime()
@cable.subscribers.notifyAll("disconnected")
-
- reconnect: ->
- @disconnect()
-
- setTimeout =>
- @incrementConnectionAttemptsCount()
- @connect()
- , @generateReconnectInterval()
-
- removeExistingConnection: ->
- if @websocket?
- @clearPingWaitTimeout()
-
- @websocket.onclose = -> # no-op
- @websocket.onerror = -> # no-op
- @websocket.close()
- @websocket = null
-
- resetConnectionAttemptsCount: ->
- @connectionAttempts = 1
-
- incrementConnectionAttemptsCount: ->
- @connectionAttempts += 1
-
- generateReconnectInterval: () ->
- interval = (Math.pow(2, @connectionAttempts) - 1) * 1000
- if interval > @MAX_CONNECTION_INTERVAL then @MAX_CONNECTION_INTERVAL else interval
-
- startWaitingForPing: ->
- @clearPingWaitTimeout()
-
- @waitForPingTimeout = setTimeout =>
- console.log "Ping took too long to arrive. Reconnecting.."
- @reconnect()
- , @PING_STALE_INTERVAL * 1000
-
- clearPingWaitTimeout: ->
- clearTimeout(@waitForPingTimeout)
-
- resetPingTime: ->
- @lastPingTime = null
-
- pingReceived: (timestamp) ->
- if @lastPingTime? and (timestamp - @lastPingTime) > @PING_STALE_INTERVAL
- console.log "Websocket connection is stale. Reconnecting.."
- @reconnect()
- else
- @startWaitingForPing()
- @lastPingTime = timestamp
+ @removeWebsocket()
diff --git a/lib/assets/javascripts/cable/connection_monitor.js.coffee b/lib/assets/javascripts/cable/connection_monitor.js.coffee
new file mode 100644
index 0000000000..078e1d3b26
--- /dev/null
+++ b/lib/assets/javascripts/cable/connection_monitor.js.coffee
@@ -0,0 +1,41 @@
+class Cable.ConnectionMonitor
+ MAX_CONNECTION_INTERVAL: 5 * 1000
+ PING_STALE_INTERVAL: 8 * 1000
+
+ identifier: Cable.PING_IDENTIFIER
+
+ constructor: (@cable) ->
+ @reset()
+ @cable.subscribers.add(this)
+ @pollConnection()
+
+ connected: ->
+ @reset()
+ @pingedAt = now()
+
+ received: ->
+ @pingedAt = now()
+
+ reset: ->
+ @connectionAttempts = 1
+
+ pollConnection: ->
+ setTimeout =>
+ @reconnect() if @connectionIsStale()
+ @pollConnection()
+ , @getPollTimeout()
+
+ getPollTimeout: ->
+ interval = (Math.pow(2, @connectionAttempts) - 1) * 1000
+ if interval > @MAX_CONNECTION_INTERVAL then @MAX_CONNECTION_INTERVAL else interval
+
+ connectionIsStale: ->
+ @pingedAt? and (now() - @pingedAt) > @PING_STALE_INTERVAL
+
+ reconnect: ->
+ console.log "Ping took too long to arrive. Reconnecting.."
+ @connectionAttempts += 1
+ @cable.connection.connect()
+
+ now = ->
+ new Date().getTime()
diff --git a/lib/assets/javascripts/cable/subscriber_manager.js.coffee b/lib/assets/javascripts/cable/subscriber_manager.js.coffee
index e2e6c9e228..d76832a802 100644
--- a/lib/assets/javascripts/cable/subscriber_manager.js.coffee
+++ b/lib/assets/javascripts/cable/subscriber_manager.js.coffee
@@ -30,4 +30,5 @@ class Cable.SubscriberManager
subscriber[event]?(args...)
sendCommand: (command, identifier) ->
+ return true if identifier is Cable.PING_IDENTIFIER
@cable.send({command, identifier})