Move assets to the gem

This commit is contained in:
Pratik Naik 2015-02-12 20:47:26 +05:30
parent 00aec9c8e8
commit 2c0c9a17d0
4 changed files with 140 additions and 0 deletions

View File

@ -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'

View File

@ -0,0 +1,4 @@
module ActionCable
class Engine < ::Rails::Engine
end
end

View 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

View 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)