Class: Rage::Cable::Protocols::ActioncableV1Json
- Defined in:
- lib/rage/cable/protocols/actioncable_v1_json.rb
Overview
This is an implementation of the Action Cable protocol. Clients are expected to use
@rails/actioncable to connect to the server.
Defined Under Namespace
Modules: COMMAND, MESSAGES, REASON, TYPE
Constant Summary collapse
- HANDSHAKE_HEADERS =
{ "Sec-WebSocket-Protocol" => "actioncable-v1-json" }
Class Method Summary collapse
-
.init ⇒ Object
This method serves as a constructor to prepare the object or set up recurring tasks (e.g. heartbeats).
-
.on_close(connection, env, router) ⇒ Object
The method should process client disconnections and call Router#process_disconnection.
-
.on_message(connection, env, raw_data, router) ⇒ Object
The method processes messages from existing connections.
-
.on_open(connection, env, router) ⇒ Object
The method is called any time a new WebSocket connection is established.
-
.on_remote_disconnect(connection, options) ⇒ Object
Process the disconnect initiated by the server.
-
.protocol_definition ⇒ Object
The method defines the headers to send to the client after the handshake process.
-
.protocol_id ⇒ String
A unique identifier of the protocol used in multi-server setups by PubSub.
-
.serialize(params, data) ⇒ Object
Serialize a Ruby object into the format the client would understand.
Methods inherited from Base
broadcast, subscribe, supports_rpc?, unsubscribe
Class Method Details
.init ⇒ Object
This method serves as a constructor to prepare the object or set up recurring tasks (e.g. heartbeats).
73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 73 def self.init super Iodine.on_state(:on_start) do ping_counter = Time.now.to_i Iodine.run_every(3000) do ping_counter += 1 Iodine.publish("cable:ping", { type: TYPE::PING, message: ping_counter }.to_json, Iodine::PubSub::PROCESS) end end end |
.on_close(connection, env, router) ⇒ Object
This method is optional.
The method should process client disconnections and call Router#process_disconnection.
156 157 158 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 156 def self.on_close(connection, env, router) router.process_disconnection(connection, env) end |
.on_message(connection, env, raw_data, router) ⇒ Object
The method processes messages from existing connections. It should parse the message, call either Router#process_subscription or Router#process_message, and handle its return value.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 111 def self.(connection, env, raw_data, router) parsed_data = Rage::ParamsParser.json_parse(raw_data) command, identifier = parsed_data[:command], parsed_data[:identifier] params = Rage::ParamsParser.json_parse(identifier) # process subscription messages if command == COMMAND::SUBSCRIBE status = router.process_subscription(connection, env, identifier, params[:channel], params) if status == :subscribed connection.write({ identifier: identifier, type: TYPE::CONFIRM }.to_json) elsif status == :rejected connection.write({ identifier: identifier, type: TYPE::REJECT }.to_json) elsif status == :invalid connection.write(MESSAGES::INVALID) end return elsif command == COMMAND::UNSUBSCRIBE router.process_unsubscription(connection, env, identifier) return end # process data messages; # plain `JSON` is used here to conform with the ActionCable API that passes `data` as a Hash with string keys; data = JSON.parse(parsed_data[:data]) = if command == COMMAND::MESSAGE && data.has_key?("action") router.(connection, env, identifier, data["action"].to_sym, data) elsif command == COMMAND::MESSAGE router.(connection, env, identifier, :receive, data) end unless == :processed connection.write(MESSAGES::INVALID) end end |
.on_open(connection, env, router) ⇒ Object
The method is called any time a new WebSocket connection is established. It is expected to call Router#process_connection and handle its return value.
92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 92 def self.on_open(connection, env, router) accepted = router.process_connection(connection, env) if accepted connection.subscribe("cable:ping") connection.write(MESSAGES::WELCOME) else connection.write(MESSAGES::UNAUTHORIZED) connection.close end end |
.on_remote_disconnect(connection, options) ⇒ Object
Process the disconnect initiated by the server.
178 179 180 181 182 183 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 178 def self.on_remote_disconnect(connection, ) reconnect = .nil? || .fetch(:reconnect, true) = reconnect ? MESSAGES::DISCONNECT : MESSAGES::DISCONNECT_NO_RECONNECT connection.write() end |
.protocol_definition ⇒ Object
The method defines the headers to send to the client after the handshake process.
68 69 70 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 68 def self.protocol_definition HANDSHAKE_HEADERS end |
.protocol_id ⇒ String
A unique identifier of the protocol used in multi-server setups by PubSub.
170 171 172 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 170 def self.protocol_id "acv1" end |
.serialize(params, data) ⇒ Object
Serialize a Ruby object into the format the client would understand.
164 165 166 |
# File 'lib/rage/cable/protocols/actioncable_v1_json.rb', line 164 def self.serialize(params, data) { identifier: params.to_json, message: data }.to_json end |