Class: Melaya::MelayaWebSocket
- Inherits:
-
Object
- Object
- Melaya::MelayaWebSocket
- Defined in:
- lib/melaya/stream.rb
Overview
A minimal RFC 6455 WebSocket client built on stdlib TCP+TLS. No external gem required. Supports text frames; yields parsed JSON frames.
Usage (block form — closes automatically):
MelayaWebSocket.connect(url, verify_ssl: true) do |ws|
ws.each_frame { |frame| puts frame.inspect; break }
end
Usage (manual):
ws = MelayaWebSocket.new(url, verify_ssl: true)
ws.connect
ws.each_frame { |f| ... }
ws.close
Constant Summary collapse
- GUID =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
Class Method Summary collapse
Instance Method Summary collapse
- #close ⇒ Object
- #connect ⇒ Object
-
#each_frame ⇒ Object
Iterate over incoming JSON frames.
-
#initialize(url, verify_ssl: true) ⇒ MelayaWebSocket
constructor
A new instance of MelayaWebSocket.
Constructor Details
#initialize(url, verify_ssl: true) ⇒ MelayaWebSocket
Returns a new instance of MelayaWebSocket.
44 45 46 47 48 49 50 |
# File 'lib/melaya/stream.rb', line 44 def initialize(url, verify_ssl: true) @uri = URI.parse(url) @verify_ssl = verify_ssl @socket = nil @closed = false @buf = String.new("", encoding: "BINARY") end |
Class Method Details
.connect(url, verify_ssl: true, &block) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/melaya/stream.rb', line 30 def self.connect(url, verify_ssl: true, &block) ws = new(url, verify_ssl: verify_ssl) ws.connect if block_given? begin block.call(ws) ensure ws.close end else ws end end |
Instance Method Details
#close ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/melaya/stream.rb', line 91 def close return if @closed @closed = true begin # Send a close frame (opcode 0x8) with no body, masked send_frame(0x8, "") rescue StandardError # best-effort ensure @socket&.close rescue nil end end |
#connect ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/melaya/stream.rb', line 52 def connect tcp = TCPSocket.new(@uri.host, @uri.port) @socket = if @uri.scheme == "wss" ctx = OpenSSL::SSL::SSLContext.new ctx.verify_mode = @verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE ssl = OpenSSL::SSL::SSLSocket.new(tcp, ctx) ssl.hostname = @uri.host ssl.connect ssl else tcp end handshake self end |
#each_frame ⇒ Object
Iterate over incoming JSON frames. Yields each parsed frame Hash. Blocks until the socket closes or the block calls break.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/melaya/stream.rb', line 72 def each_frame loop do frame = read_frame break if frame.nil? # connection closed next if frame.empty? # ping/pong or non-text begin yield JSON.parse(frame) rescue JSON::ParserError next # ignore non-JSON keep-alive text end end rescue IOError, Errno::ECONNRESET, EOFError # socket closed by remote ensure close end |