Class: Rage::Cable::Channel

Inherits:
Object
  • Object
show all
Defined in:
lib/rage/cable/channel.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.after_subscribe(action_name = nil, **opts, &block) ⇒ Object

Note:

This callback will be triggered even if the subscription was rejected with the #reject method.

Register a new after_subscribe hook that will be called after the #subscribed method.

Examples:

after_subscribe do
  ...
end
after_subscribe :my_method, unless: :subscription_rejected?


209
210
211
# File 'lib/rage/cable/channel.rb', line 209

def after_subscribe(action_name = nil, **opts, &block)
  add_action(:after_subscribe, action_name, **opts, &block)
end

.after_unsubscribe(action_name = nil, **opts, &block) ⇒ Object

Register a new after_unsubscribe hook that will be called after the #unsubscribed method.



219
220
221
# File 'lib/rage/cable/channel.rb', line 219

def after_unsubscribe(action_name = nil, **opts, &block)
  add_action(:after_unsubscribe, action_name, **opts, &block)
end

.before_subscribe(action_name = nil, **opts, &block) ⇒ Object

Register a new before_subscribe hook that will be called before the #subscribed method.

Examples:

before_subscribe :my_method
before_subscribe do
  ...
end
before_subscribe :my_method, if: -> { ... }


196
197
198
# File 'lib/rage/cable/channel.rb', line 196

def before_subscribe(action_name = nil, **opts, &block)
  add_action(:before_subscribe, action_name, **opts, &block)
end

.before_unsubscribe(action_name = nil, **opts, &block) ⇒ Object

Register a new before_unsubscribe hook that will be called before the #unsubscribed method.



214
215
216
# File 'lib/rage/cable/channel.rb', line 214

def before_unsubscribe(action_name = nil, **opts, &block)
  add_action(:before_unsubscribe, action_name, **opts, &block)
end

.periodically(method_name = nil, every:, &block) ⇒ Object

Set up a timer to periodically perform a task on the channel. Accepts a method name or a block.

Examples:

periodically every: 3.minutes do
  transmit({ action: :update_count, count: current_count })
end
periodically :update_count, every: 3.minutes

Parameters:

  • method_name (Symbol, nil) (defaults to: nil)

    the name of the method to call

  • every (Integer)

    the calling period in seconds



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/rage/cable/channel.rb', line 267

def periodically(method_name = nil, every:, &block)
  callback_name = if block_given?
    raise ArgumentError, "Pass the `method_name` argument or provide a block, not both" if method_name
    define_tmp_method(block)
  elsif method_name.is_a?(Symbol)
    define_tmp_method(eval("-> { #{method_name} }"))
  else
    raise ArgumentError, "Expected a Symbol method name, got #{method_name.inspect}"
  end

  unless every.is_a?(Numeric) && every > 0
    raise ArgumentError, "Expected every: to be a positive number of seconds, got #{every.inspect}"
  end

  callback = eval("->(channel) { channel.#{callback_name} }")

  if @__periodic_timers.nil?
    @__periodic_timers = []
  elsif @__periodic_timers.frozen?
    @__periodic_timers = @__periodic_timers.dup
  end

  @__periodic_timers << [callback, every]
end

.rescue_from(*klasses, with: nil, &block) ⇒ Object

Register an exception handler.

Examples:

rescue_from StandardError, with: :report_error

private

def report_error(e)
  SomeExternalBugtrackingService.notify(e)
end
rescue_from StandardError do |e|
  SomeExternalBugtrackingService.notify(e)
end

Parameters:

  • klasses (Class, Array<Class>)

    exception classes to watch on

  • with (Symbol) (defaults to: nil)

    the name of a handler method. The method can take one argument, which is the raised exception. Alternatively, you can pass a block, which can also take one argument.



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/rage/cable/channel.rb', line 239

def rescue_from(*klasses, with: nil, &block)
  unless with
    if block_given?
      with = define_tmp_method(block)
    else
      raise ArgumentError, "No handler provided. Pass the `with` keyword argument or provide a block."
    end
  end

  if @__rescue_handlers.nil?
    @__rescue_handlers = []
  elsif @__rescue_handlers.frozen?
    @__rescue_handlers = @__rescue_handlers.dup
  end

  @__rescue_handlers.unshift([klasses, with])
end

Instance Method Details

#broadcast(stream, data) ⇒ Object

Broadcast data to all the clients subscribed to a stream.

Examples:

def subscribed
  broadcast("notifications", { message: "A new member has joined!" })
end

Parameters:

  • stream (String)

    the name of the stream

  • data (Object)

    the data to send to the clients



420
421
422
# File 'lib/rage/cable/channel.rb', line 420

def broadcast(stream, data)
  Rage.config.cable.protocol.broadcast(stream, data)
end

#paramsHash{Symbol=>String,Array,Hash,Numeric,NilClass,TrueClass,FalseClass}

Get the params hash passed in during the subscription process.

Returns:

  • (Hash{Symbol=>String,Array,Hash,Numeric,NilClass,TrueClass,FalseClass})


388
389
390
# File 'lib/rage/cable/channel.rb', line 388

def params
  @__params
end

#rejectObject

Reject the subscription request. The method should only be called during the subscription process (i.e. inside the #subscribed method or before_subscribe/after_subscribe hooks).



394
395
396
# File 'lib/rage/cable/channel.rb', line 394

def reject
  @__subscription_rejected = true
end

#stream_from(stream) ⇒ Object

Subscribe to a stream.

Parameters:

  • stream (String)

    the name of the stream



408
409
410
# File 'lib/rage/cable/channel.rb', line 408

def stream_from(stream)
  Rage.config.cable.protocol.subscribe(@__connection, stream, @__params)
end

#subscribedObject

Called once a client has become a subscriber of the channel.



444
445
# File 'lib/rage/cable/channel.rb', line 444

def subscribed
end

#subscription_rejected?Boolean

Checks whether the #reject method has been called.

Returns:

  • (Boolean)


401
402
403
# File 'lib/rage/cable/channel.rb', line 401

def subscription_rejected?
  !!@__subscription_rejected
end

#transmit(data) ⇒ Object

Transmit data to the current client.

Examples:

def subscribed
  transmit({ message: "Hello!" })
end

Parameters:

  • data (Object)

    the data to send to the client



431
432
433
434
435
436
437
438
439
440
441
# File 'lib/rage/cable/channel.rb', line 431

def transmit(data)
  message = Rage.config.cable.protocol.serialize(@__params, data)

  if @__is_subscribing
    # we expect a confirmation message to be sent as a result of a successful subscribe call;
    # this will make sure `transmit` calls send data after the confirmation;
    ::Iodine.defer { @__connection.write(message) }
  else
    @__connection.write(message)
  end
end

#unsubscribedObject

Called once a client unsubscribes from the channel.



448
449
# File 'lib/rage/cable/channel.rb', line 448

def unsubscribed
end