Class: Utcp::Providers::WebSocketProvider
- Inherits:
-
BaseProvider
- Object
- BaseProvider
- Utcp::Providers::WebSocketProvider
- Defined in:
- lib/utcp/providers/websocket_provider.rb
Overview
Minimal RFC 6455 WebSocket client (text frames only) Supports ws:// and wss:// (TLS). Client frames are masked; server frames are unmasked.
Constant Summary collapse
- GUID =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11".freeze
Instance Attribute Summary
Attributes inherited from BaseProvider
Instance Method Summary collapse
-
#call_tool(tool, arguments = {}, &block) ⇒ Object
tool.provider expects: { “provider_type”:“websocket”, “url”:“ws(s)://host/path”, “message_template”: “…optional…” , “close_after_ms”: 3000, “max_frames”: 1 } If a block is given, yields each received text frame (streaming).
- #discover_tools! ⇒ Object
-
#initialize(name:, auth: nil) ⇒ WebSocketProvider
constructor
A new instance of WebSocketProvider.
Constructor Details
#initialize(name:, auth: nil) ⇒ WebSocketProvider
18 19 20 |
# File 'lib/utcp/providers/websocket_provider.rb', line 18 def initialize(name:, auth: nil) super(name: name, provider_type: "websocket", auth: auth) end |
Instance Method Details
#call_tool(tool, arguments = {}, &block) ⇒ Object
tool.provider expects: { “provider_type”:“websocket”, “url”:“ws(s)://host/path”, “message_template”: “…optional…” ,
"close_after_ms": 3000, "max_frames": 1 }
If a block is given, yields each received text frame (streaming).
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/utcp/providers/websocket_provider.rb', line 30 def call_tool(tool, arguments = {}, &block) p = tool.provider uri = URI(Utils::Subst.apply(p["url"])) raise ConfigError, "WebSocket requires ws:// or wss:// URL" unless %w[ws wss].include?(uri.scheme) sock = connect_socket(uri) begin handshake(sock, uri) # Compose a text message to send payload = compose_payload(p, arguments) if payload send_text(sock, payload) end # Read frames; stop based on configuration close_after = (p["close_after_ms"] || 3000).to_i max_frames = (p["max_frames"] || 1).to_i deadline = Time.now + (close_after / 1000.0) frames = [] while Time.now < deadline && frames.length < max_frames frame = recv_frame(sock, deadline: deadline) break unless frame case frame[:opcode] when 0x1 # text if block_given? yield frame[:payload] else frames << frame[:payload] end when 0x8 # close break when 0x9 # ping send_pong(sock, frame[:payload]) when 0xA # pong # ignore else # ignore other opcodes end end block_given? ? nil : frames ensure begin send_close(sock) rescue end sock.close rescue nil end end |
#discover_tools! ⇒ Object
22 23 24 |
# File 'lib/utcp/providers/websocket_provider.rb', line 22 def discover_tools! raise ProviderError, "WebSocket is an execution provider only" end |