lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee in websocket-rails-0.6.2 vs lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee in websocket-rails-0.7.0
- old
+ new
@@ -16,28 +16,59 @@
console.log(data.user_name);
});
###
class @WebSocketRails
constructor: (@url, @use_websockets = true) ->
- @state = 'connecting'
@callbacks = {}
@channels = {}
@queue = {}
+ @connect()
+
+ connect: ->
+ @state = 'connecting'
+
unless @supports_websockets() and @use_websockets
- @_conn = new WebSocketRails.HttpConnection url, @
+ @_conn = new WebSocketRails.HttpConnection @url, @
else
- @_conn = new WebSocketRails.WebSocketConnection url, @
+ @_conn = new WebSocketRails.WebSocketConnection @url, @
@_conn.new_message = @new_message
+ disconnect: ->
+ if @_conn
+ @_conn.close()
+ delete @_conn._conn
+ delete @_conn
+
+ @state = 'disconnected'
+
+ # Reconnects the whole connection,
+ # keeping the messages queue and its' connected channels.
+ #
+ # After successfull connection, this will:
+ # - reconnect to all channels, that were active while disconnecting
+ # - resend all events from which we haven't received any response yet
+ reconnect: =>
+ old_connection_id = @_conn?.connection_id
+
+ @disconnect()
+ @connect()
+
+ # Resend all unfinished events from the previous connection.
+ for id, event of @queue
+ if event.connection_id == old_connection_id && !event.is_result()
+ @trigger_event event
+
+ @reconnect_channels()
+
new_message: (data) =>
for socket_message in data
event = new WebSocketRails.Event( socket_message )
if event.is_result()
@queue[event.id]?.run_callbacks(event.success, event.data)
- @queue[event.id] = null
+ delete @queue[event.id]
else if event.is_channel()
@dispatch_channel event
else if event.is_ping()
@pong()
else
@@ -46,44 +77,44 @@
if @state == 'connecting' and event.name == 'client_connected'
@connection_established event.data
connection_established: (data) =>
@state = 'connected'
- @connection_id = data.connection_id
- @_conn.flush_queue data.connection_id
+ @_conn.setConnectionId(data.connection_id)
+ @_conn.flush_queue()
if @on_open?
@on_open(data)
bind: (event_name, callback) =>
@callbacks[event_name] ?= []
@callbacks[event_name].push callback
trigger: (event_name, data, success_callback, failure_callback) =>
- event = new WebSocketRails.Event( [event_name, data, @connection_id], success_callback, failure_callback )
- @queue[event.id] = event
- @_conn.trigger event
+ event = new WebSocketRails.Event( [event_name, data, @_conn?.connection_id], success_callback, failure_callback )
+ @trigger_event event
trigger_event: (event) =>
@queue[event.id] ?= event # Prevent replacing an event that has callbacks stored
- @_conn.trigger event
+ @_conn.trigger event if @_conn
+ event
dispatch: (event) =>
return unless @callbacks[event.name]?
for callback in @callbacks[event.name]
callback event.data
- subscribe: (channel_name) =>
+ subscribe: (channel_name, success_callback, failure_callback) =>
unless @channels[channel_name]?
- channel = new WebSocketRails.Channel channel_name, @
+ channel = new WebSocketRails.Channel channel_name, @, false, success_callback, failure_callback
@channels[channel_name] = channel
channel
else
@channels[channel_name]
- subscribe_private: (channel_name) =>
+ subscribe_private: (channel_name, success_callback, failure_callback) =>
unless @channels[channel_name]?
- channel = new WebSocketRails.Channel channel_name, @, true
+ channel = new WebSocketRails.Channel channel_name, @, true, success_callback, failure_callback
@channels[channel_name] = channel
channel
else
@channels[channel_name]
@@ -98,10 +129,24 @@
supports_websockets: =>
(typeof(WebSocket) == "function" or typeof(WebSocket) == "object")
pong: =>
- pong = new WebSocketRails.Event( ['websocket_rails.pong',{},@connection_id] )
+ pong = new WebSocketRails.Event( ['websocket_rails.pong', {}, @_conn?.connection_id] )
@_conn.trigger pong
connection_stale: =>
@state != 'connected'
+
+ # Destroy and resubscribe to all existing @channels.
+ reconnect_channels: ->
+ for name, channel of @channels
+ callbacks = channel._callbacks
+ channel.destroy()
+ delete @channels[name]
+
+ channel = if channel.is_private
+ @subscribe_private name
+ else
+ @subscribe name
+ channel._callbacks = callbacks
+ channel