Class: Ferrum::Client
- Inherits:
-
Object
- Object
- Ferrum::Client
- Extended by:
- Forwardable
- Defined in:
- lib/ferrum/client.rb,
lib/ferrum/client/subscriber.rb,
lib/ferrum/client/web_socket.rb
Overview
The low-level CDP client. Owns the WebSocket connection to the browser, assigns command ids, matches responses back to their pending commands and dispatches incoming events to the Subscriber. SessionClient builds on top of it to scope commands/events to a particular target's session.
Defined Under Namespace
Classes: Subscriber, WebSocket
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#subscriber ⇒ Object
readonly
Returns the value of attribute subscriber.
-
#ws_url ⇒ Object
readonly
Returns the value of attribute ws_url.
Instance Method Summary collapse
-
#build_message(method, params) ⇒ Hash
Builds a CDP message hash with a fresh, thread-safe command id.
-
#close ⇒ void
Closes the underlying websocket, drops pending commands and stops the message-processing thread and subscriber.
-
#command(method, async: false, timeout: nil, **params) ⇒ Boolean, Hash
Sends a CDP command to the browser-wide session.
-
#initialize(ws_url, options) ⇒ Client
constructor
A new instance of Client.
-
#inspect ⇒ String
Custom inspection that exposes internal state useful for debugging.
-
#off(event, id) ⇒ void
Unsubscribes from a CDP event.
-
#on(event) ⇒ Integer
Subscribes to a CDP event.
-
#send_message(message, async:, timeout: nil) ⇒ Boolean, Hash
Sends a raw CDP message over the websocket.
-
#session(session_id) ⇒ SessionClient
Builds a client scoped to a given CDP session, e.g.
-
#subscribed?(event) ⇒ Boolean
Whether there's at least one callback registered for the event.
Constructor Details
#initialize(ws_url, options) ⇒ Client
Returns a new instance of Client.
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/ferrum/client.rb', line 157 def initialize(ws_url, ) @command_id = 0 @command_id_mutex = Mutex.new @ws_url = ws_url @options = @pendings = Concurrent::Hash.new @ws = WebSocket.new(ws_url, .ws_max_receive_size, .logger) @subscriber = Subscriber.new start end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
155 156 157 |
# File 'lib/ferrum/client.rb', line 155 def @options end |
#subscriber ⇒ Object (readonly)
Returns the value of attribute subscriber.
155 156 157 |
# File 'lib/ferrum/client.rb', line 155 def subscriber @subscriber end |
#ws_url ⇒ Object (readonly)
Returns the value of attribute ws_url.
155 156 157 |
# File 'lib/ferrum/client.rb', line 155 def ws_url @ws_url end |
Instance Method Details
#build_message(method, params) ⇒ Hash
Builds a CDP message hash with a fresh, thread-safe command id.
325 326 327 |
# File 'lib/ferrum/client.rb', line 325 def (method, params) { method: method, params: params }.merge(id: next_command_id) end |
#close ⇒ void
This method returns an undefined value.
Closes the underlying websocket, drops pending commands and stops the message-processing thread and subscriber.
294 295 296 297 298 299 300 |
# File 'lib/ferrum/client.rb', line 294 def close @ws.close # Give a thread some time to handle a tail of messages @pendings.clear @thread.kill unless @thread.join(1) @subscriber.close end |
#command(method, async: false, timeout: nil, **params) ⇒ Boolean, Hash
Sends a CDP command to the browser-wide session.
188 189 190 191 |
# File 'lib/ferrum/client.rb', line 188 def command(method, async: false, timeout: nil, **params) = (method, params) (, async: async, timeout: timeout) end |
#inspect ⇒ String
Custom inspection that exposes internal state useful for debugging.
307 308 309 310 311 312 |
# File 'lib/ferrum/client.rb', line 307 def inspect "#<#{self.class} " \ "@command_id=#{@command_id.inspect} " \ "@pendings=#{@pendings.inspect} " \ "@ws=#{@ws.inspect}>" end |
#off(event, id) ⇒ void
This method returns an undefined value.
Unsubscribes from a CDP event.
261 262 263 |
# File 'lib/ferrum/client.rb', line 261 def off(event, id) @subscriber.off(event, id) end |
#on(event) ⇒ Integer
Subscribes to a CDP event.
246 247 248 |
# File 'lib/ferrum/client.rb', line 246 def on(event, &) @subscriber.on(event, &) end |
#send_message(message, async:, timeout: nil) ⇒ Boolean, Hash
Sends a raw CDP message over the websocket. Synchronous calls block
until a matching response arrives, or timeout elapses, defaulting to
protocol_timeout (delegated to Browser::Options#protocol_timeout).
That default is the transport-level budget for internal CDP bookkeeping
(e.g. Target.createTarget). Page#command overrides
this back to timeout, or a caller-supplied budget (e.g. #pdf/
#screenshot's own timeout: argument), for the user-facing commands
it issues -- some of which (e.g. Page.navigate, Page.printToPDF)
rely on their own response latency to detect a stuck operation.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/ferrum/client.rb', line 217 def (, async:, timeout: nil) if async @ws.() true else pending = Concurrent::IVar.new @pendings[[:id]] = pending @ws.() data = pending.value!(timeout || protocol_timeout) @pendings.delete([:id]) raise DeadBrowserError if data.nil? && @ws..closed? raise TimeoutError unless data error, response = data.values_at("error", "result") raise_browser_error(error) if error response end end |
#session(session_id) ⇒ SessionClient
Builds a client scoped to a given CDP session, e.g. a browsing
context created via Target.attachToTarget.
284 285 286 |
# File 'lib/ferrum/client.rb', line 284 def session(session_id) SessionClient.new(self, session_id) end |
#subscribed?(event) ⇒ Boolean
Whether there's at least one callback registered for the event.
271 272 273 |
# File 'lib/ferrum/client.rb', line 271 def subscribed?(event) @subscriber.subscribed?(event) end |