Class: Ferrum::Client::WebSocket
- Inherits:
-
Object
- Object
- Ferrum::Client::WebSocket
- Defined in:
- lib/ferrum/client/web_socket.rb
Constant Summary collapse
- WEBSOCKET_BUG_SLEEP =
0.05
- DEFAULT_PORTS =
{ "ws" => 80, "wss" => 443 }.freeze
- SKIP_LOGGING_SCREENSHOTS =
!ENV["FERRUM_LOGGING_SCREENSHOTS"]
Instance Attribute Summary collapse
-
#messages ⇒ Object
readonly
Returns the value of attribute messages.
-
#url ⇒ Object
readonly
Returns the value of attribute url.
Instance Method Summary collapse
- #close ⇒ Object
-
#initialize(url, max_receive_size, logger) ⇒ WebSocket
constructor
A new instance of WebSocket.
- #on_close(_event) ⇒ Object
- #on_message(event) ⇒ Object
- #on_open(_event) ⇒ Object
- #send_message(data) ⇒ Object
- #write(data) ⇒ Object
Constructor Details
#initialize(url, max_receive_size, logger) ⇒ WebSocket
Returns a new instance of WebSocket.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/ferrum/client/web_socket.rb', line 16 def initialize(url, max_receive_size, logger) @url = url @logger = logger uri = URI.parse(@url) port = uri.port || DEFAULT_PORTS[uri.scheme] if port == 443 tcp = TCPSocket.new(uri.host, port) ssl_context = OpenSSL::SSL::SSLContext.new @sock = OpenSSL::SSL::SSLSocket.new(tcp, ssl_context) @sock.sync_close = true @sock.connect else @sock = TCPSocket.new(uri.host, port) end max_receive_size ||= ::WebSocket::Driver::MAX_LENGTH @driver = ::WebSocket::Driver.client(self, max_length: max_receive_size) @messages = Queue.new @screenshot_commands = Concurrent::Hash.new if SKIP_LOGGING_SCREENSHOTS @driver.on(:open, &method(:on_open)) @driver.on(:message, &method(:on_message)) @driver.on(:close, &method(:on_close)) start @driver.start end |
Instance Attribute Details
#messages ⇒ Object (readonly)
Returns the value of attribute messages.
14 15 16 |
# File 'lib/ferrum/client/web_socket.rb', line 14 def @messages end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
14 15 16 |
# File 'lib/ferrum/client/web_socket.rb', line 14 def url @url end |
Instance Method Details
#close ⇒ Object
89 90 91 |
# File 'lib/ferrum/client/web_socket.rb', line 89 def close @driver.close end |
#on_close(_event) ⇒ Object
69 70 71 72 73 |
# File 'lib/ferrum/client/web_socket.rb', line 69 def on_close(_event) @messages.close @sock.close @thread.kill end |
#on_message(event) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/ferrum/client/web_socket.rb', line 52 def (event) data = safely_parse_json(event.data) # If we couldn't parse JSON data for some reason (parse error or deeply nested object) we # don't push response to @messages. Worse that could happen we raise timeout error due to command didn't return # anything or skip the background notification, but at least we don't crash the thread that crashes the main # thread and the application. @messages.push(data) if data output = event.data if SKIP_LOGGING_SCREENSHOTS && @screenshot_commands[data&.dig("id")] @screenshot_commands.delete(data&.dig("id")) output.sub!(/{"data":"[^"]*"}/, %("Set FERRUM_LOGGING_SCREENSHOTS=true to see screenshots in Base64")) end @logger&.puts(" ◀ #{Utils::ElapsedTime.elapsed_time} #{output}\n") end |
#on_open(_event) ⇒ Object
47 48 49 50 |
# File 'lib/ferrum/client/web_socket.rb', line 47 def on_open(_event) # https://github.com/faye/websocket-driver-ruby/issues/46 sleep(WEBSOCKET_BUG_SLEEP) end |
#send_message(data) ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/ferrum/client/web_socket.rb', line 75 def (data) @screenshot_commands[data[:id]] = true if SKIP_LOGGING_SCREENSHOTS json = data.to_json @driver.text(json) @logger&.puts("\n\n▶ #{Utils::ElapsedTime.elapsed_time} #{json}") end |
#write(data) ⇒ Object
83 84 85 86 87 |
# File 'lib/ferrum/client/web_socket.rb', line 83 def write(data) @sock.write(data) rescue EOFError, Errno::ECONNRESET, Errno::EPIPE, IOError # rubocop:disable Lint/ShadowedException @messages.close end |