Class: Tep::WebSocket::Driver
- Inherits:
-
Object
- Object
- Tep::WebSocket::Driver
- Defined in:
- lib/tep/websocket/driver.rb
Instance Attribute Summary collapse
-
#fd ⇒ Object
Returns the value of attribute fd.
-
#h_close ⇒ Object
Callback slots.
-
#h_error ⇒ Object
Callback slots.
-
#h_message ⇒ Object
Callback slots.
-
#h_open ⇒ Object
Callback slots.
-
#h_ping ⇒ Object
Callback slots.
-
#h_pong ⇒ Object
Callback slots.
-
#max_frame_size ⇒ Object
Returns the value of attribute max_frame_size.
-
#subprotocol ⇒ Object
Returns the value of attribute subprotocol.
Class Method Summary collapse
-
.encode_close_payload(code, reason) ⇒ Object
Close payload: 2-byte big-endian code + UTF-8 reason.
-
.send_frame(fd, opcode, payload) ⇒ Object
Build the frame bytes (unmasked, server-side) and write via sphttp_write_bytes (binary-safe, explicit length).
Instance Method Summary collapse
-
#binary(bytes) ⇒ Object
Send a binary frame.
-
#close(code, reason) ⇒ Object
Send a close frame with code + reason.
-
#initialize(fd) ⇒ Driver
constructor
A new instance of Driver.
-
#ping(payload) ⇒ Object
Send a ping with optional payload (<=125 bytes).
-
#pong(payload) ⇒ Object
Send a pong with the matching ping’s payload (per §5.5.3).
-
#set_fd(new_fd) ⇒ Object
Reassign the underlying fd.
- #set_max_frame_size(n) ⇒ Object
- #set_on_close(h) ⇒ Object
- #set_on_error(h) ⇒ Object
- #set_on_message(h) ⇒ Object
- #set_on_open(h) ⇒ Object
- #set_on_ping(h) ⇒ Object
- #set_on_pong(h) ⇒ Object
- #set_subprotocol(name) ⇒ Object
-
#text(s) ⇒ Object
Send a text frame.
-
#write(s) ⇒ Object
Streamer-shape alias for ‘text` so a Driver can stand in anywhere `Tep::Streamer`-style code calls `out.write(s)`.
Constructor Details
#initialize(fd) ⇒ Driver
Returns a new instance of Driver.
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/tep/websocket/driver.rb', line 34 def initialize(fd) @fd = fd @max_frame_size = Tep::WebSocket::DEFAULT_MAX_FRAME @subprotocol = "" @h_open = Tep::WebSocket::Handler.new @h_message = Tep::WebSocket::Handler.new @h_close = Tep::WebSocket::Handler.new @h_ping = Tep::WebSocket::Handler.new @h_pong = Tep::WebSocket::Handler.new @h_error = Tep::WebSocket::Handler.new end |
Instance Attribute Details
#fd ⇒ Object
Returns the value of attribute fd.
27 28 29 |
# File 'lib/tep/websocket/driver.rb', line 27 def fd @fd end |
#h_close ⇒ Object
Callback slots. Each holds a subclass of Tep::WebSocket::Handler (or the base) that gets ‘handle_event(event)` called when the corresponding wire event arrives. Defaults to a no-op base so the slot is type-safe pre-set.
32 33 34 |
# File 'lib/tep/websocket/driver.rb', line 32 def h_close @h_close end |
#h_error ⇒ Object
Callback slots. Each holds a subclass of Tep::WebSocket::Handler (or the base) that gets ‘handle_event(event)` called when the corresponding wire event arrives. Defaults to a no-op base so the slot is type-safe pre-set.
32 33 34 |
# File 'lib/tep/websocket/driver.rb', line 32 def h_error @h_error end |
#h_message ⇒ Object
Callback slots. Each holds a subclass of Tep::WebSocket::Handler (or the base) that gets ‘handle_event(event)` called when the corresponding wire event arrives. Defaults to a no-op base so the slot is type-safe pre-set.
32 33 34 |
# File 'lib/tep/websocket/driver.rb', line 32 def @h_message end |
#h_open ⇒ Object
Callback slots. Each holds a subclass of Tep::WebSocket::Handler (or the base) that gets ‘handle_event(event)` called when the corresponding wire event arrives. Defaults to a no-op base so the slot is type-safe pre-set.
32 33 34 |
# File 'lib/tep/websocket/driver.rb', line 32 def h_open @h_open end |
#h_ping ⇒ Object
Callback slots. Each holds a subclass of Tep::WebSocket::Handler (or the base) that gets ‘handle_event(event)` called when the corresponding wire event arrives. Defaults to a no-op base so the slot is type-safe pre-set.
32 33 34 |
# File 'lib/tep/websocket/driver.rb', line 32 def h_ping @h_ping end |
#h_pong ⇒ Object
Callback slots. Each holds a subclass of Tep::WebSocket::Handler (or the base) that gets ‘handle_event(event)` called when the corresponding wire event arrives. Defaults to a no-op base so the slot is type-safe pre-set.
32 33 34 |
# File 'lib/tep/websocket/driver.rb', line 32 def h_pong @h_pong end |
#max_frame_size ⇒ Object
Returns the value of attribute max_frame_size.
27 28 29 |
# File 'lib/tep/websocket/driver.rb', line 27 def max_frame_size @max_frame_size end |
#subprotocol ⇒ Object
Returns the value of attribute subprotocol.
27 28 29 |
# File 'lib/tep/websocket/driver.rb', line 27 def subprotocol @subprotocol end |
Class Method Details
.encode_close_payload(code, reason) ⇒ Object
Close payload: 2-byte big-endian code + UTF-8 reason. Per §5.5.1 the payload may be omitted (close with no body); if ‘code == 0` we emit an empty payload.
117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/tep/websocket/driver.rb', line 117 def self.encode_close_payload(code, reason) if code == 0 return "" end out = Tep::WebSocket::Frame.byte_to_chr((code >> 8) & 0xff) + Tep::WebSocket::Frame.byte_to_chr(code & 0xff) if reason.length > 123 out + reason[0, 123] else out + reason end end |
.send_frame(fd, opcode, payload) ⇒ Object
Build the frame bytes (unmasked, server-side) and write via sphttp_write_bytes (binary-safe, explicit length).
108 109 110 111 112 |
# File 'lib/tep/websocket/driver.rb', line 108 def self.send_frame(fd, opcode, payload) frame = Tep::WebSocket::Frame.new(true, opcode, payload) bytes = frame.encode_unmasked Sock.sphttp_write_bytes(fd, bytes, bytes.length) end |
Instance Method Details
#binary(bytes) ⇒ Object
Send a binary frame.
84 85 86 |
# File 'lib/tep/websocket/driver.rb', line 84 def binary(bytes) Driver.send_frame(@fd, Tep::WebSocket::OPCODE_BINARY, bytes) end |
#close(code, reason) ⇒ Object
Send a close frame with code + reason. Reason capped at 123 bytes so the 2-byte code + reason fits in a control frame’s 125-byte payload limit.
101 102 103 104 |
# File 'lib/tep/websocket/driver.rb', line 101 def close(code, reason) body = Driver.encode_close_payload(code, reason) Driver.send_frame(@fd, Tep::WebSocket::OPCODE_CLOSE, body) end |
#ping(payload) ⇒ Object
Send a ping with optional payload (<=125 bytes).
89 90 91 |
# File 'lib/tep/websocket/driver.rb', line 89 def ping(payload) Driver.send_frame(@fd, Tep::WebSocket::OPCODE_PING, payload) end |
#pong(payload) ⇒ Object
Send a pong with the matching ping’s payload (per §5.5.3).
94 95 96 |
# File 'lib/tep/websocket/driver.rb', line 94 def pong(payload) Driver.send_frame(@fd, Tep::WebSocket::OPCODE_PONG, payload) end |
#set_fd(new_fd) ⇒ Object
Reassign the underlying fd. Used by the server-side upgrade path: the user handler builds the Driver with a placeholder fd (since the client fd isn’t visible at handler-dispatch time), and the write_response branch sets the real fd here right before constructing the Connection.
55 56 57 |
# File 'lib/tep/websocket/driver.rb', line 55 def set_fd(new_fd) @fd = new_fd end |
#set_max_frame_size(n) ⇒ Object
46 47 48 |
# File 'lib/tep/websocket/driver.rb', line 46 def set_max_frame_size(n) @max_frame_size = n end |
#set_on_close(h) ⇒ Object
65 |
# File 'lib/tep/websocket/driver.rb', line 65 def set_on_close(h); @h_close = h; end |
#set_on_error(h) ⇒ Object
68 |
# File 'lib/tep/websocket/driver.rb', line 68 def set_on_error(h); @h_error = h; end |
#set_on_message(h) ⇒ Object
64 |
# File 'lib/tep/websocket/driver.rb', line 64 def (h); @h_message = h; end |
#set_on_open(h) ⇒ Object
63 |
# File 'lib/tep/websocket/driver.rb', line 63 def set_on_open(h); @h_open = h; end |
#set_on_ping(h) ⇒ Object
66 |
# File 'lib/tep/websocket/driver.rb', line 66 def set_on_ping(h); @h_ping = h; end |
#set_on_pong(h) ⇒ Object
67 |
# File 'lib/tep/websocket/driver.rb', line 67 def set_on_pong(h); @h_pong = h; end |
#set_subprotocol(name) ⇒ Object
59 60 61 |
# File 'lib/tep/websocket/driver.rb', line 59 def set_subprotocol(name) @subprotocol = name end |
#text(s) ⇒ Object
Send a text frame.
71 72 73 |
# File 'lib/tep/websocket/driver.rb', line 71 def text(s) Driver.send_frame(@fd, Tep::WebSocket::OPCODE_TEXT, s) end |
#write(s) ⇒ Object
Streamer-shape alias for ‘text` so a Driver can stand in anywhere `Tep::Streamer`-style code calls `out.write(s)`. Used by Tep::Llm.chat_stream to write LLM deltas as WS frames (one frame per SSE-shaped chunk).
79 80 81 |
# File 'lib/tep/websocket/driver.rb', line 79 def write(s) Driver.send_frame(@fd, Tep::WebSocket::OPCODE_TEXT, s) end |