mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Move assets to the gem
This commit is contained in:
parent
00aec9c8e8
commit
2c0c9a17d0
4 changed files with 140 additions and 0 deletions
|
@ -12,6 +12,8 @@ require 'active_support/callbacks'
|
|||
require 'faye/websocket'
|
||||
require 'celluloid'
|
||||
|
||||
require 'action_cable/engine' if defined?(Rails)
|
||||
|
||||
module ActionCable
|
||||
VERSION = '0.0.1'
|
||||
|
||||
|
|
4
lib/action_cable/engine.rb
Normal file
4
lib/action_cable/engine.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
module ActionCable
|
||||
class Engine < ::Rails::Engine
|
||||
end
|
||||
end
|
107
lib/assets/javascripts/cable.js.coffee
Normal file
107
lib/assets/javascripts/cable.js.coffee
Normal file
|
@ -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
|
27
lib/assets/javascripts/channel.js.coffee
Normal file
27
lib/assets/javascripts/channel.js.coffee
Normal file
|
@ -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)
|
Loading…
Reference in a new issue