Class: Puppeteer::Connection

Inherits:
Object
  • Object
show all
Includes:
DebugPrint, EventCallbackable
Defined in:
lib/puppeteer/connection.rb

Defined Under Namespace

Classes: MessageCallback, ProtocolError, RequestDebugPrinter, ResponseDebugPrinter

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from EventCallbackable

#add_event_listener, #emit_event, #observe_first, #off, #on_event, #remove_event_listener

Methods included from DebugPrint

#debug_print, #debug_puts

Constructor Details

#initialize(url, transport, delay = 0, protocol_timeout: nil) ⇒ Connection

Returns a new instance of Connection.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/puppeteer/connection.rb', line 40

def initialize(url, transport, delay = 0, protocol_timeout: nil)
  @url = url
  @last_id = 0
  @callbacks = {}
  @callbacks_mutex = Mutex.new
  @delay = delay
  @protocol_timeout = protocol_timeout

  @network_message_queue = Async::Queue.new
  @network_message_task = nil

  @transport = transport
  @transport.on_message do |data|
    message = JSON.parse(data)
    sleep_before_handling_message(message)
    if network_event_message?(message)
      enqueue_network_message(message)
    elsif should_handle_synchronously?(message)
      handle_message(message)
    else
      async_handle_message(message)
    end
  end
  @transport.on_close do |reason, code|
    handle_close
  end

  @sessions = {}
  @sessions_mutex = Mutex.new
  @closed = false
  @manually_attached = Set.new
end

Instance Attribute Details

#protocol_timeoutObject (readonly)

Returns the value of attribute protocol_timeout.



73
74
75
# File 'lib/puppeteer/connection.rb', line 73

def protocol_timeout
  @protocol_timeout
end

Class Method Details

.from_session(session) ⇒ Object



150
151
152
# File 'lib/puppeteer/connection.rb', line 150

def self.from_session(session)
  session.connection
end

Instance Method Details

#async_send_message(method, params = {}) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/puppeteer/connection.rb', line 178

def async_send_message(method, params = {})
  promise = Async::Promise.new

  generate_id do |id|
    @callbacks_mutex.synchronize do
      @callbacks[id] = MessageCallback.new(method: method, promise: promise)
    end
    raw_send(id: id, message: { method: method, params: params })
  end

  promise
end

#auto_attached?(target_id) ⇒ Boolean

Returns:

  • (Boolean)


383
384
385
# File 'lib/puppeteer/connection.rb', line 383

def auto_attached?(target_id)
  !@manually_attached.include?(target_id)
end

#closed?Boolean

used only in Browser#connected?

Returns:

  • (Boolean)


76
77
78
# File 'lib/puppeteer/connection.rb', line 76

def closed?
  @closed
end

#create_session(target_info, auto_attach_emulated: false) ⇒ CDPSession

Parameters:

  • targetInfo (Protocol.Target.TargetInfo)

Returns:



389
390
391
392
393
394
395
396
397
# File 'lib/puppeteer/connection.rb', line 389

def create_session(target_info, auto_attach_emulated: false)
  unless auto_attach_emulated
    @manually_attached << target_info.target_id
  end
  result = send_message('Target.attachToTarget', targetId: target_info.target_id, flatten: true)
  session_id = result['sessionId']
  @manually_attached.delete(target_info.target_id)
  @sessions_mutex.synchronize { @sessions[session_id] }.tap { |session| session&.mark_ready }
end

#disposeObject



378
379
380
381
# File 'lib/puppeteer/connection.rb', line 378

def dispose
  handle_close
  @transport.close
end

#generate_id(&block) ⇒ Object

package private. not intended to use externally.

“‘usage connection.generate_id do |generated_id|

# play with generated_id

end ““



199
200
201
# File 'lib/puppeteer/connection.rb', line 199

def generate_id(&block)
  block.call(@last_id += 1)
end

#on_close(&block) ⇒ Object



370
371
372
# File 'lib/puppeteer/connection.rb', line 370

def on_close(&block)
  @on_close = block
end

#on_message(&block) ⇒ Object



374
375
376
# File 'lib/puppeteer/connection.rb', line 374

def on_message(&block)
  @on_message = block
end

#raw_send(id:, message:) ⇒ Object

package private. not intended to use externally.



204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/puppeteer/connection.rb', line 204

def raw_send(id:, message:)
  # In original puppeteer (JS) implementation,
  # id is generated here using #generate_id and the id argument is not passed to #raw_send.
  #
  # However with concurrent-ruby, '#handle_message' is sometimes called
  # just soon after @transport.send_text and **before returning the id.**
  #
  # So we have to know the message id in advance before send_text.
  #
  payload = JSON.generate(message.compact.merge(id: id))
  @transport.send_text(payload)
  request_debug_printer.handle_payload(payload)
end

#send_message(method, params = {}) ⇒ Object

Parameters:

  • method (string)
  • params (!Object=) (defaults to: {})


166
167
168
169
170
171
172
173
174
175
176
# File 'lib/puppeteer/connection.rb', line 166

def send_message(method, params = {})
  if @protocol_timeout && @protocol_timeout > 0
    begin
      Puppeteer::AsyncUtils.async_timeout(@protocol_timeout, async_send_message(method, params)).wait
    rescue Async::TimeoutError
      raise ProtocolError.new(method: method, error_message: "Timeout #{@protocol_timeout}ms exceeded")
    end
  else
    async_send_message(method, params).wait
  end
end

#session(session_id) ⇒ ?CDPSession

Parameters:

  • sessionId (string)

Returns:



156
157
158
# File 'lib/puppeteer/connection.rb', line 156

def session(session_id)
  @sessions_mutex.synchronize { @sessions[session_id] }
end

#urlObject



160
161
162
# File 'lib/puppeteer/connection.rb', line 160

def url
  @url
end