3 files changed
+54
No files matched your search
@@ -354,6 +354,14 @@ object HermesWsClient {
|
||||
wsScope.launch {
|
||||
events.collect { event ->
|
||||
if (event is WsEvent.GatewayReady) {
|
||||
// Advertise support for gateway server→client requests (issue #1197).
|
||||
// Older gateways may reject this method; that is harmless.
|
||||
runCatching {
|
||||
send(
|
||||
WsMethods.CLIENT_CAPABILITIES,
|
||||
mapOf("server_requests" to true),
|
||||
)
|
||||
}
|
||||
val epoch = event.data?.get("replay_epoch") as? String
|
||||
if (!epoch.isNullOrEmpty()) {
|
||||
if (replayEpoch != null && replayEpoch != epoch) {
|
||||
|
||||
@@ -66,6 +66,7 @@ object WsMethods {
|
||||
|
||||
/** Inline WebSocket read-loop ping, bypasses server thread pool dispatch. */
|
||||
const val GATEWAY_PING = "gateway.ping"
|
||||
const val CLIENT_CAPABILITIES = "client.capabilities"
|
||||
|
||||
// ── Commands catalog ──────────────────────────────────────────────────
|
||||
const val COMMANDS_CATALOG = "commands.catalog"
|
||||
|
||||
@@ -176,6 +176,51 @@ class HermesWsClientTest {
|
||||
assertTrue(msg.contains(id))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun gatewayReadyAdvertisesServerRequestCapability() {
|
||||
val capabilityLatch = CountDownLatch(1)
|
||||
var capabilityFrame: String? = null
|
||||
|
||||
mockWebServer.enqueue(
|
||||
MockResponse().withWebSocketUpgrade(
|
||||
object : WebSocketListener() {
|
||||
override fun onOpen(
|
||||
webSocket: WebSocket,
|
||||
response: okhttp3.Response,
|
||||
) {
|
||||
webSocket.send(
|
||||
"""{"jsonrpc":"2.0","method":"event","params":{"type":"gateway.ready","payload":{}}}""",
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMessage(
|
||||
webSocket: WebSocket,
|
||||
text: String,
|
||||
) {
|
||||
val frame = Json.parseToJsonElement(text).jsonObject
|
||||
if (frame["method"]?.jsonPrimitive?.content == WsMethods.CLIENT_CAPABILITIES) {
|
||||
capabilityFrame = text
|
||||
capabilityLatch.countDown()
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
HermesWsClient.connect()
|
||||
|
||||
assertTrue("Capability advertisement not sent", capabilityLatch.await(5, TimeUnit.SECONDS))
|
||||
val frame = Json.parseToJsonElement(capabilityFrame ?: "{}").jsonObject
|
||||
assertEquals(WsMethods.CLIENT_CAPABILITIES, frame["method"]?.jsonPrimitive?.content)
|
||||
assertTrue(
|
||||
frame["params"]
|
||||
?.jsonObject
|
||||
?.get("server_requests")
|
||||
?.jsonPrimitive
|
||||
?.content == "true",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOpenRequestsReplayUsesTheLiveServerRequestDispatcher() =
|
||||
runBlocking {
|
||||
|
||||
Reference in new issue
Block a user