Class: Puppeteer::WebSocketTransport

Inherits:
Object
  • Object
show all
Defined in:
lib/puppeteer/web_socket_transport.rb

Defined Under Namespace

Classes: ClosedError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ WebSocketTransport

Returns a new instance of WebSocketTransport.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/puppeteer/web_socket_transport.rb', line 18

def initialize(url)
  @url = url
  # Force HTTP/1.1 for WebSocket connections.
  # Some servers (e.g., Google Cloud Run) advertise HTTP/2 via ALPN but don't
  # properly support WebSocket over HTTP/2 (RFC 8441), causing stream errors.
  @endpoint = Async::HTTP::Endpoint.parse(url, alpn_protocols: ["http/1.1"])
  @connection = nil
  @task = nil
  @closed = false
  @connected = false
  @on_message = nil
  @on_close = nil
  @connect_promise = nil
  @write_mutex = Mutex.new
end

Class Method Details

.create(url) ⇒ Puppeteer::WebSocketTransport

Parameters:

  • url (string)

Returns:



12
13
14
15
16
# File 'lib/puppeteer/web_socket_transport.rb', line 12

def self.create(url)
  transport = new(url)
  transport.connect.wait
  transport
end

Instance Method Details

#closeObject



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/puppeteer/web_socket_transport.rb', line 70

def close
  return if @closed

  @closed = true
  begin
    @connection&.close
  rescue Async::Stop
    # Connection already closing; ignore.
  end
  @on_close&.call(nil, nil)
  begin
    @task&.stop
  rescue Async::Stop
    # Task was already stopping; ignore.
  end
rescue IOError, Errno::ECONNRESET, Errno::EPIPE
  @on_close&.call(nil, nil)
end

#closed?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/puppeteer/web_socket_transport.rb', line 101

def closed?
  @closed
end

#connectObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/puppeteer/web_socket_transport.rb', line 34

def connect
  return @connect_promise if @connect_promise

  @connect_promise = Async::Promise.new
  @task = Async do |task|
    Async::WebSocket::Client.connect(@endpoint) do |connection|
      @connection = connection
      @connected = true
      @connect_promise.resolve(true) unless @connect_promise.resolved?
      receive_loop(connection)
    end
  rescue Async::Stop
    # Task was stopped; ignore.
  rescue => err
    @connect_promise.reject(err) unless @connect_promise.resolved?
    close
  ensure
    @connected = false
  end

  @connect_promise
end

#connected?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/puppeteer/web_socket_transport.rb', line 97

def connected?
  @connected && !@closed
end

#on_close(&block) ⇒ Object



89
90
91
# File 'lib/puppeteer/web_socket_transport.rb', line 89

def on_close(&block)
  @on_close = block
end

#on_message(&block) ⇒ Object



93
94
95
# File 'lib/puppeteer/web_socket_transport.rb', line 93

def on_message(&block)
  @on_message = block
end

#send_text(message) ⇒ Object

Parameters:

  • message (String)


58
59
60
61
62
63
64
65
66
67
68
# File 'lib/puppeteer/web_socket_transport.rb', line 58

def send_text(message)
  raise ClosedError.new("Transport is closed") if @closed

  @write_mutex.synchronize do
    @connection&.write(message)
    @connection&.flush
  end
rescue IOError, Errno::ECONNRESET, Errno::EPIPE
  close
  raise
end