Class: Daytona::SocketIOClient
- Inherits:
-
Object
- Object
- Daytona::SocketIOClient
- Defined in:
- lib/daytona/common/socketio_client.rb
Overview
Minimal Engine.IO/Socket.IO v4 client over raw WebSocket. Supports connect with auth, heartbeat, and event reception.
Engine.IO v4 heartbeat protocol (WebSocket transport):
- Server sends PING (type 2) every pingInterval ms
- Client must respond with PONG (type 3) within pingTimeout ms
- Client monitors for missing server PINGs to detect dead connections
Constant Summary collapse
- EIO_OPEN =
Engine.IO v4 packet types
'0'- EIO_CLOSE =
'1'- EIO_PING =
'2'- EIO_PONG =
'3'- EIO_MESSAGE =
'4'- SIO_CONNECT =
Socket.IO v4 packet types (inside Engine.IO messages)
'0'- SIO_DISCONNECT =
'1'- SIO_EVENT =
'2'- SIO_CONNECT_ERROR =
'4'
Instance Attribute Summary collapse
-
#connected ⇒ Object
readonly
Returns the value of attribute connected.
Instance Method Summary collapse
-
#close ⇒ Object
Gracefully close the connection.
-
#connect ⇒ Boolean
Establish the WebSocket connection and perform Socket.IO handshake.
- #connected? ⇒ Boolean
-
#initialize(api_url:, token:, organization_id: nil, on_event: nil, on_disconnect: nil, connect_timeout: 5) ⇒ SocketIOClient
constructor
A new instance of SocketIOClient.
Constructor Details
#initialize(api_url:, token:, organization_id: nil, on_event: nil, on_disconnect: nil, connect_timeout: 5) ⇒ SocketIOClient
Returns a new instance of SocketIOClient.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/daytona/common/socketio_client.rb', line 42 def initialize(api_url:, token:, organization_id: nil, on_event: nil, on_disconnect: nil, connect_timeout: 5) @api_url = api_url @token = token @organization_id = organization_id @on_event = on_event @on_disconnect = on_disconnect @connect_timeout = connect_timeout @connected = false @mutex = Mutex.new @write_mutex = Mutex.new @health_thread = nil @ping_interval = 25 @ping_timeout = 20 @last_server_activity = Time.now @ws = nil @close_requested = false end |
Instance Attribute Details
#connected ⇒ Object (readonly)
Returns the value of attribute connected.
34 35 36 |
# File 'lib/daytona/common/socketio_client.rb', line 34 def connected @connected end |
Instance Method Details
#close ⇒ Object
Gracefully close the connection.
115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/daytona/common/socketio_client.rb', line 115 def close @close_requested = true @health_thread&.kill @health_thread = nil send_raw(EIO_CLOSE) if @ws @ws&.close @mutex.synchronize { @connected = false } rescue StandardError # Ignore errors during close end |
#connect ⇒ Boolean
Establish the WebSocket connection and perform Socket.IO handshake.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/daytona/common/socketio_client.rb', line 63 def connect ws_url = build_ws_url connected_queue = Queue.new # Capture self because websocket-client-simple uses instance_exec for callbacks client = self @ws = WebSocket::Client::Simple.connect(ws_url) @ws.on :message do |msg| client.send(:handle_raw_message, msg.data.to_s, connected_queue) end @ws.on :error do |_e| client.instance_variable_get(:@mutex).synchronize do client.instance_variable_set(:@connected, false) end connected_queue.push(:error) unless client.connected? end @ws.on :close do mutex = client.instance_variable_get(:@mutex) was_connected = mutex.synchronize do prev = client.instance_variable_get(:@connected) client.instance_variable_set(:@connected, false) prev end on_disconnect = client.instance_variable_get(:@on_disconnect) close_requested = client.instance_variable_get(:@close_requested) on_disconnect&.call if was_connected && !close_requested end # Wait for connection with timeout result = nil begin Timeout.timeout(@connect_timeout) { result = connected_queue.pop } rescue Timeout::Error close raise "WebSocket connection timed out after #{@connect_timeout}s" end raise "WebSocket connection failed: #{result}" if result != :connected @mutex.synchronize { @connected } end |
#connected? ⇒ Boolean
110 111 112 |
# File 'lib/daytona/common/socketio_client.rb', line 110 def connected? @mutex.synchronize { @connected } end |