class ActionCableClient
Constants
- VERSION
Attributes
The queue should store entries in the format:
- action, data
The queue should store entries in the format:
- action, data
Public Class Methods
@param [String] uri - e.g.: ws://domain:port @param [String] params - the name of the channel on the Rails server
or params. This gets sent with every request. e.g.: RoomChannel
@param [Boolean] connect_on_start - connects on init when true
- otherwise manually call `connect!`
@param [Hash] headers - HTTP headers to use in the handshake @param [Hash] tls - TLS options hash to be passed to EM start_tls
# File lib/action_cable_client.rb, line 39 def initialize(uri, params = '', connect_on_start = true, headers = {}, tls = {}) @_uri = uri @message_queue = [] @_subscribed = false @_message_factory = MessageFactory.new(params) connect!(headers, tls) if connect_on_start end
Public Instance Methods
# File lib/action_cable_client.rb, line 49 def connect!(headers = {}, tls = {}) # Quick Reference for WebSocket::EM::Client's api # - onopen - called after successfully connecting # - onclose - called after closing connection # - onmessage - called when client recives a message. on `message do |msg, type (text or binary)|`` # - also called when a ping is received # - onerror - called when client encounters an error # - onping - called when client receives a ping from the server # - onpong - called when client receives a pong from the server # - send - sends a message to the server (and also disables any metaprogramming shenanigans :-/) # - close - closes the connection and optionally sends close frame to server. `close(code, data)` # - ping - sends a ping # - pong - sends a pong @_websocket_client = WebSocket::EventMachine::Client.connect(uri: @_uri, headers: headers, tls: tls) @_websocket_client.onclose do self._subscribed = false _disconnected_callback&.call end end
callback when the client connects to the server
@example
client = ActionCableClient.new(uri, 'RoomChannel') client.connected do # do things after the client is connected to the server end
# File lib/action_cable_client.rb, line 106 def connected self._connected_callback = proc do |json| yield(json) end end
callback when the server disconnects from the client.
@example
client = ActionCableClient.new(uri, 'RoomChannel') client.connected {} client.disconnected do # cleanup after the server disconnects from the client end
# File lib/action_cable_client.rb, line 142 def disconnected self._disconnected_callback = proc do yield end end
@param [String] action - how the message is being sent @param [Hash] data - the message to be sent to the channel
# File lib/action_cable_client.rb, line 78 def perform(action, data) dispatch_message(action, data) end
# File lib/action_cable_client.rb, line 148 def pinged(&block) self._pinged_callback = block end
callback for received messages as well as what triggers depleting the message queue
@example
client = ActionCableClient.new(uri, 'RoomChannel') client.received do |message| # the received message will be JSON puts message end
# File lib/action_cable_client.rb, line 91 def received _websocket_client.onmessage do |message, _type| handle_received_message(message) do |json| yield(json) end end end
# File lib/action_cable_client.rb, line 70 def reconnect! uri = URI(@_uri) EventMachine.reconnect uri.host, uri.port, @_websocket_client @_websocket_client.post_init end
callback when the client receives a confirm_subscription message from the action_cable server. This is only called once, and signifies that you can now send messages on the channel
@param [Proc] block - code to run after subscribing to the channel is confirmed
@example
client = ActionCableClient.new(uri, 'RoomChannel') client.connected {} client.subscribed do # do things after successful subscription confirmation end
# File lib/action_cable_client.rb, line 125 def subscribed(&block) self._subscribed_callback = block end
@return [Boolean] is the client subscribed to the channel?
# File lib/action_cable_client.rb, line 130 def subscribed? _subscribed end
Private Instance Methods
{“identifier” => “_ping”,“type” => “confirm_subscription”}
# File lib/action_cable_client.rb, line 175 def check_for_subscribe_confirmation(message) message_type = message[Message::TYPE_KEY] return unless Message::TYPE_CONFIRM_SUBSCRIPTION == message_type self._subscribed = true _subscribed_callback&.call end
# File lib/action_cable_client.rb, line 201 def dispatch_message(action, data) # can't send messages if we aren't subscribed return unless subscribed? msg = _message_factory.create(Commands::MESSAGE, action, data) json = msg.to_json send_msg(json) end
@param [String] message - the websockt message object
# File lib/action_cable_client.rb, line 155 def handle_received_message(message) return if message.empty? json = JSON.parse(message) if is_ping?(json) _pinged_callback&.call(json) elsif is_welcome?(json) subscribe _connected_callback&.call(json) elsif !subscribed? check_for_subscribe_confirmation(json) else # TODO: do we want to yield any additional things? # maybe just make it extensible? yield(json) end end
{“identifier” => “_ping”,“message” => 1460201942} {“identifier” => “_ping”,“type” => “confirm_subscription”}
# File lib/action_cable_client.rb, line 185 def is_ping?(message) message_identifier = message[Message::TYPE_KEY] Message::IDENTIFIER_PING == message_identifier end
{“type” => “welcome”}
# File lib/action_cable_client.rb, line 191 def is_welcome?(message) message_identifier = message[Message::TYPE_KEY] Message::IDENTIFIER_WELCOME == message_identifier end
# File lib/action_cable_client.rb, line 196 def subscribe msg = _message_factory.create(Commands::SUBSCRIBE) send_msg(msg.to_json) end