aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/app/assets/javascripts/action_cable/connection.coffee
diff options
context:
space:
mode:
authorkp <keith.j.payne@gmail.com>2016-02-10 17:44:54 +0000
committerkp <keith.j.payne@gmail.com>2016-02-10 17:44:54 +0000
commitec4ae308a76bd86fb6eaf7fa8ee025af0063ee30 (patch)
tree741019b3fbf474ff4cdeefdbeb6ff1f598ffcdfc /actioncable/app/assets/javascripts/action_cable/connection.coffee
parent8641de93eb98d4ebdb0db2530c8c79c0c4e2f95e (diff)
parent688996da7b25080a1a2ef74f5b4789f3e5eb670d (diff)
downloadrails-ec4ae308a76bd86fb6eaf7fa8ee025af0063ee30.tar.gz
rails-ec4ae308a76bd86fb6eaf7fa8ee025af0063ee30.tar.bz2
rails-ec4ae308a76bd86fb6eaf7fa8ee025af0063ee30.zip
Merge remote-tracking branch 'origin/master' into actioncable_logging
Diffstat (limited to 'actioncable/app/assets/javascripts/action_cable/connection.coffee')
-rw-r--r--actioncable/app/assets/javascripts/action_cable/connection.coffee81
1 files changed, 81 insertions, 0 deletions
diff --git a/actioncable/app/assets/javascripts/action_cable/connection.coffee b/actioncable/app/assets/javascripts/action_cable/connection.coffee
new file mode 100644
index 0000000000..fbd7dbd35b
--- /dev/null
+++ b/actioncable/app/assets/javascripts/action_cable/connection.coffee
@@ -0,0 +1,81 @@
+# Encapsulate the cable connection held by the consumer. This is an internal class not intended for direct user manipulation.
+
+{message_types} = ActionCable.INTERNAL
+
+class ActionCable.Connection
+ @reopenDelay: 500
+
+ constructor: (@consumer) ->
+ @open()
+
+ send: (data) ->
+ if @isOpen()
+ @webSocket.send(JSON.stringify(data))
+ true
+ else
+ false
+
+ open: =>
+ if @webSocket and not @isState("closed")
+ throw new Error("Existing connection must be closed before opening")
+ else
+ @webSocket = new WebSocket(@consumer.url)
+ @installEventHandlers()
+ true
+
+ close: ->
+ @webSocket?.close()
+
+ reopen: ->
+ if @isState("closed")
+ @open()
+ else
+ try
+ @close()
+ finally
+ setTimeout(@open, @constructor.reopenDelay)
+
+ isOpen: ->
+ @isState("open")
+
+ # Private
+
+ isState: (states...) ->
+ @getState() in states
+
+ getState: ->
+ return state.toLowerCase() for state, value of WebSocket when value is @webSocket?.readyState
+ null
+
+ installEventHandlers: ->
+ for eventName of @events
+ handler = @events[eventName].bind(this)
+ @webSocket["on#{eventName}"] = handler
+ return
+
+ events:
+ message: (event) ->
+ {identifier, message, type} = JSON.parse(event.data)
+
+ switch type
+ when message_types.confirmation
+ @consumer.subscriptions.notify(identifier, "connected")
+ when message_types.rejection
+ @consumer.subscriptions.reject(identifier)
+ else
+ @consumer.subscriptions.notify(identifier, "received", message)
+
+ open: ->
+ @disconnected = false
+ @consumer.subscriptions.reload()
+
+ close: ->
+ @disconnect()
+
+ error: ->
+ @disconnect()
+
+ disconnect: ->
+ return if @disconnected
+ @disconnected = true
+ @consumer.subscriptions.notifyAll("disconnected")