You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
FoxgloveClient.callService against foxglove_bridge >= 3.2.6 (foxglove-sdk-cpp v0.18.0+) hung until timeout because the bridge rejects JSON-encoded service requests even when it advertises supportedEncodings: ["cdr", "json"] — that capability applies to topic messages, not service calls. Service-call requests are now CDR-encoded using the per-service requestSchema shipped by the bridge in advertiseServices; the response is decoded with the corresponding responseSchema. The fix is backward-compatible with older bridges (CDR is the canonical ROS 2 service encoding and has always been accepted). Verified at the wire level against ROS Jazzy + foxglove_bridge 3.2.6.
FoxgloveClient now handles the serviceCallFailure op alongside serviceCallResponse. Failures from the bridge (unknown service, malformed request, schema mismatch, unsupported encoding) reject the in-flight call promise immediately with the bridge's message instead of being silently dropped until the 30 s timeout.
FoxgloveClient.callService against schemaless service advertisements now works for empty requests.foxglove_bridge 3.2.6+ commonly advertises services with their type name but without inline request-schema text — the normal shape for services discovered via ROS 2 graph introspection rather than explicit .srv files. The client now detects this case: if the caller's request is empty ({}, null, or undefined), it sends only the 4-byte CDR encapsulation header and the bridge default-constructs the request server-side from the known type. Non-empty requests against schemaless services still surface a clear error explaining the limitation (the encoder genuinely cannot serialize without field-layout information).
FoxgloveClient.callService now resolves request and response schemas through a layered fallback. Order of resolution: (1) the bridge-advertised requestSchema / responseSchema (authoritative when present), (2) a bundled IDL for six well-known ROS 2 system services — rcl_interfaces/srv/{ListParameters,GetParameters,SetParameters,DescribeParameters,GetParameterTypes} and action_msgs/srv/CancelGoal — which foxglove_bridge 3.2.6+ commonly discovers via introspection without shipping schemas inline, (3) the 4-byte encapsulation-header fallback for empty requests when neither source has a schema. Parameter operations and action cancellation now work against any compliant bridge configuration, not only ones that ship .srv-derived schemas. When defs are available, an empty caller request {} is now filled with zero values via schemaToTemplate rather than rejected on missing fields, making {} a stable "default request" sentinel across sim and real-bridge setups.
FoxgloveClient now dispatches inbound binary opcode 0x03 SERVICE_CALL_RESPONSE frames. Previous revisions consumed only the JSON-op response shape; foxglove-sdk-cpp 0.18.0+ defaults to the binary 0x03 frame for every service-call response, so pending callIds never resolved and surfaced as 30-second timeouts. The binary path and the legacy JSON-op path now route through a shared decoder; both CDR and JSON response payloads are handled.
FoxgloveClient now sends SERVICE_CALL_REQUEST as the spec-defined binary opcode 0x02 frame instead of the JSON op of the same name. The JSON form is not in the Foxglove WS v1 spec and is rejected by current bridges with a level-2 status message, leaving callIds hanging until the 30-second timeout.
FoxgloveClient no longer emits the JSON ping keep-alive every 5 seconds. The op is not in the Foxglove WS v1 spec; modern bridges emit a level-2 status in response to each one. WebSocket-level RFC 6455 ping/pong handles connection liveness at the transport layer and does not need application-level emulation. Existing pong responses from older bridges are ignored without error.
FoxgloveClient now fast-fails in-flight service calls when the bridge sends a level-2 status message naming serviceCallRequest. These undirected status messages do not carry a callId, so prior versions had no way to associate them with the failing call and all in-flight callIds hung until their 30-second timeout. The substring match keeps the rejection scoped to service-call surfaces; unrelated level-2 messages do not tear down healthy calls.
FoxgloveClient outbound binary frames are now sent as Uint8Array, not raw ArrayBuffer. React Native's WebSocket native bridge silently drops send(ArrayBuffer) payloads above roughly 400 bytes; this manifested as 16-name get_parameters requests never leaving the device (confirmed via tcpdump). Sending via Uint8Array uses a different RN native serializer that handles every payload size we send. Same bytes on the wire for browsers and Node; this is load-bearing for React Native consumers and is covered by a regression test.
Changed
ProtocolClientOptions.onLatency is no longer driven by FoxgloveClient as a consequence of removing the JSON ping/pong keep-alive (see Fixed). The option remains in the public type and is still driven by RosbridgeClient via its dedicated latency-probe path. Foxglove WS RTT measurement will return when a portable spec-compliant signal is available; browsers do not expose ws.ping() from JavaScript.