Class: RubyLens::Clip::WebSocketChannel
- Inherits:
-
Object
- Object
- RubyLens::Clip::WebSocketChannel
- Defined in:
- lib/rubylens/clip/web_socket_channel.rb
Overview
Minimal RFC 6455 client for Chrome's local DevTools WebSocket endpoint, so clip rendering needs no gem or Node dependencies. Client frames are masked text; ping, close, and fragmented server frames are handled; extensions are never negotiated.
Constant Summary collapse
- HANDSHAKE_GUID =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"- TEXT_OPCODE =
1- CONTINUATION_OPCODE =
0- CLOSE_OPCODE =
8- PING_OPCODE =
9- PONG_OPCODE =
10
Instance Method Summary collapse
- #close ⇒ Object
-
#initialize(host, port, path, timeout: 15) ⇒ WebSocketChannel
constructor
A new instance of WebSocketChannel.
- #read_text(timeout: 30) ⇒ Object
- #send_text(payload) ⇒ Object
Constructor Details
#initialize(host, port, path, timeout: 15) ⇒ WebSocketChannel
Returns a new instance of WebSocketChannel.
24 25 26 27 28 29 |
# File 'lib/rubylens/clip/web_socket_channel.rb', line 24 def initialize(host, port, path, timeout: 15) @socket = TCPSocket.new(host, port) @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) @buffer = +"".b handshake(host, port, path, timeout) end |
Instance Method Details
#close ⇒ Object
58 59 60 61 62 |
# File 'lib/rubylens/clip/web_socket_channel.rb', line 58 def close @socket.close unless @socket.closed? rescue IOError nil end |
#read_text(timeout: 30) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/rubylens/clip/web_socket_channel.rb', line 44 def read_text(timeout: 30) deadline = DeadlineIO.deadline(timeout) = +"".b loop do finished, opcode, payload = read_frame(deadline) case opcode when TEXT_OPCODE, CONTINUATION_OPCODE then << payload when CLOSE_OPCODE then raise Error, "Chrome closed the DevTools connection" when PING_OPCODE then send_control(PONG_OPCODE, payload) end return .force_encoding(Encoding::UTF_8) if finished && opcode <= TEXT_OPCODE && !.empty? end end |
#send_text(payload) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/rubylens/clip/web_socket_channel.rb', line 31 def send_text(payload) bytes = payload.b length = bytes.bytesize header = if length < 126 then [0x80 | TEXT_OPCODE, 0x80 | length].pack("CC") elsif length < 65_536 then [0x80 | TEXT_OPCODE, 0x80 | 126, length].pack("CCn") else [0x80 | TEXT_OPCODE, 0x80 | 127, length].pack("CCQ>") end mask = SecureRandom.bytes(4) @socket.write(header + mask + apply_mask(bytes, mask)) rescue SystemCallError, IOError => error raise Error, "lost the Chrome DevTools connection: #{error.}" end |