aboutsummaryrefslogtreecommitdiffstats
path: root/lib/assets/javascripts
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2015-02-12 20:47:26 +0530
committerPratik Naik <pratiknaik@gmail.com>2015-02-12 20:47:26 +0530
commit2c0c9a17d07832e8a4a3a50b95e1f8f15ab22d5a (patch)
tree1e9f31f4c615a06db688b42de3267bd892e48313 /lib/assets/javascripts
parent00aec9c8e8b30cfb40454ed44693465843b0d4b2 (diff)
downloadrails-2c0c9a17d07832e8a4a3a50b95e1f8f15ab22d5a.tar.gz
rails-2c0c9a17d07832e8a4a3a50b95e1f8f15ab22d5a.tar.bz2
rails-2c0c9a17d07832e8a4a3a50b95e1f8f15ab22d5a.zip
Move assets to the gem
Diffstat (limited to 'lib/assets/javascripts')
-rw-r--r--lib/assets/javascripts/cable.js.coffee107
-rw-r--r--lib/assets/javascripts/channel.js.coffee27
2 files changed, 134 insertions, 0 deletions
diff --git a/lib/assets/javascripts/cable.js.coffee b/lib/assets/javascripts/cable.js.coffee
new file mode 100644
index 0000000000..2a70693bf0
--- /dev/null
+++ b/lib/assets/javascripts/cable.js.coffee
@@ -0,0 +1,107 @@
+#= require_self
+#= require_tree .
+
+class @Cable
+ MAX_CONNECTION_ATTEMPTS: 10
+ MAX_CONNECTION_INTERVAL: 5 * 1000
+ MAX_PING_INTERVAL: 6
+
+ constructor: (@cableUrl) ->
+ @subscribers = {}
+ @resetPingTime()
+ @resetConnectionAttemptsCount()
+ @connect()
+
+ connect: ->
+ @connection = @createConnection()
+
+ createConnection: ->
+ connection = new WebSocket(@cableUrl)
+ connection.onmessage = @receiveData
+ connection.onopen = @connected
+ connection.onclose = @reconnect
+
+ connection.onerror = @reconnect
+ connection
+
+ isConnected: =>
+ @connection?.readyState is 1
+
+ sendData: (identifier, data) =>
+ if @isConnected()
+ @connection.send JSON.stringify { action: 'message', identifier: identifier, data: data }
+
+ receiveData: (message) =>
+ data = JSON.parse message.data
+
+ if data.identifier is '_ping'
+ @pingReceived(data.message)
+ else
+ @subscribers[data.identifier]?.onReceiveData(data.message)
+
+ connected: =>
+ @resetConnectionAttemptsCount()
+
+ for identifier, callbacks of @subscribers
+ @subscribeOnServer(identifier)
+ callbacks['onConnect']?()
+
+ reconnect: =>
+ @resetPingTime()
+ @disconnected()
+
+ setTimeout =>
+ if @isMaxConnectionAttemptsReached()
+ @giveUp()
+ else
+ @incrementConnectionAttemptsCount()
+ @connect()
+ , @generateReconnectInterval()
+
+ resetConnectionAttemptsCount: =>
+ @connectionAttempts = 1
+
+ incrementConnectionAttemptsCount: =>
+ @connectionAttempts += 1
+
+ isMaxConnectionAttemptsReached: =>
+ @connectionAttempts > @MAX_CONNECTION_ATTEMPTS
+
+ generateReconnectInterval: () ->
+ interval = (Math.pow(2, @connectionAttempts) - 1) * 1000
+ if interval > @MAX_CONNECTION_INTERVAL then @MAX_CONNECTION_INTERVAL else interval
+
+ resetPingTime: () =>
+ @lastPingTime = null
+
+ disconnected: =>
+ callbacks['onDisconnect']?() for identifier, callbacks of @subscribers
+
+ giveUp: =>
+ # Show an error message
+
+ subscribe: (identifier, callbacks) =>
+ @subscribers[identifier] = callbacks
+
+ if @isConnected()
+ @subscribeOnServer(identifier)
+ @subscribers[identifier]['onConnect']?()
+
+ unsubscribe: (identifier) =>
+ @unsubscribeOnServer(identifier, 'unsubscribe')
+ delete @subscribers[identifier]
+
+ subscribeOnServer: (identifier) =>
+ if @isConnected()
+ @connection.send JSON.stringify { action: 'subscribe', identifier: identifier }
+
+ unsubscribeOnServer: (identifier) =>
+ if @isConnected()
+ @connection.send JSON.stringify { action: 'unsubscribe', identifier: identifier }
+
+ pingReceived: (timestamp) =>
+ if @lastPingTime? and (timestamp - @lastPingTime) > @MAX_PING_INTERVAL
+ console.log "Websocket connection is stale. Reconnecting.."
+ @connection.close()
+ else
+ @lastPingTime = timestamp
diff --git a/lib/assets/javascripts/channel.js.coffee b/lib/assets/javascripts/channel.js.coffee
new file mode 100644
index 0000000000..058bcc03aa
--- /dev/null
+++ b/lib/assets/javascripts/channel.js.coffee
@@ -0,0 +1,27 @@
+class @Cable.Channel
+ constructor: (params = {}) ->
+ @channelName ?= @underscore @constructor.name
+
+ params['channel'] = @channelName
+ @channelIdentifier = JSON.stringify params
+
+ cable.subscribe(@channelIdentifier, {
+ onConnect: @connected
+ onDisconnect: @disconnected
+ onReceiveData: @received
+ })
+
+ connected: =>
+ # Override in the subclass
+
+ disconnected: =>
+ # Override in the subclass
+
+ received: (data) =>
+ # Override in the subclass
+
+ send: (data) ->
+ cable.sendData @channelIdentifier, JSON.stringify data
+
+ underscore: (value) ->
+ value.replace(/[A-Z]/g, (match) => "_#{match.toLowerCase()}").substr(1) \ No newline at end of file