Module: OMQ::Transport::WebSocket::Codec

Defined in:
lib/omq/transport/websocket/codec.rb

Overview

ZWS 2.0 wire codec (RFC 45). One ZeroMQ frame per WebSocket binary message, prefixed with a single FLAG byte:

0x00  final data frame   (no MORE)
0x01  intermediate data frame (MORE)
0x02  command frame      (READY/PING/PONG/SUBSCRIBE/...)

No length prefix — the WebSocket message length IS the frame length. No greeting; mechanism is negotiated via Sec-WebSocket-Protocol during the HTTP upgrade.

Constant Summary collapse

FLAG_LAST =
0x00
FLAG_MORE =
0x01
FLAG_COMMAND =
0x02
EMPTY_BINARY =
"".b.freeze

Class Method Summary collapse

Class Method Details

.decode(bytes) ⇒ Array(Integer, String)

Decodes a WS binary message into [flag_byte, body_slice].

Parameters:

  • bytes (String)

    WS binary message bytes

Returns:

  • (Array(Integer, String))

Raises:

  • (Protocol::ZMTP::Error)

    on empty message



51
52
53
54
55
56
57
# File 'lib/omq/transport/websocket/codec.rb', line 51

def self.decode(bytes)
  raise Protocol::ZMTP::Error, "ZWS frame is empty" if bytes.empty?

  flag = bytes.getbyte(0)
  body = bytes.byteslice(1, bytes.bytesize - 1) || EMPTY_BINARY
  [flag, body]
end

.encode(body, more: false, command: false) ⇒ String

Encodes a frame body with the appropriate FLAG byte prefix.

Parameters:

  • body (String)

    frame payload (binary)

  • more (Boolean) (defaults to: false)

    more frames follow in this message

  • command (Boolean) (defaults to: false)

    command frame (PING/PONG/READY/...)

Returns:

  • (String)

    WS binary message bytes (BINARY encoding)



34
35
36
37
38
39
40
41
42
# File 'lib/omq/transport/websocket/codec.rb', line 34

def self.encode(body, more: false, command: false)
  flag    = command ? FLAG_COMMAND : (more ? FLAG_MORE : FLAG_LAST)
  payload = body.encoding == Encoding::BINARY ? body : body.b
  out     = String.new(capacity: payload.bytesize + 1, encoding: Encoding::BINARY)

  out << flag.chr(Encoding::BINARY)
  out << payload
  out
end