Skip to content

Commit 72ae2de

Browse files
non-responsive input handler and ack message
1 parent 091f3d3 commit 72ae2de

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

src/js/packages/@reactpy/client/src/messages.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export type ReconnectingCheckMessage = {
1717
value: string;
1818
}
1919

20-
export type IncomingMessage = LayoutUpdateMessage | ReconnectingCheckMessage;
20+
export type AckMessage = {
21+
type: "ack"
22+
}
23+
24+
export type IncomingMessage = LayoutUpdateMessage | ReconnectingCheckMessage | AckMessage;
2125
export type OutgoingMessage = LayoutEventMessage | ReconnectingCheckMessage;
2226
export type Message = IncomingMessage | OutgoingMessage;

src/js/packages/@reactpy/client/src/reactpy-client.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ export class SimpleReactPyClient
184184
private socketLoopThrottle: number;
185185
private pingPongIntervalId?: number | null;
186186
private pingInterval: number;
187+
private messageResponseTimeoutId?: number | null;
187188

188189
constructor(props: SimpleReactPyClientProps) {
189190
super();
@@ -340,9 +341,21 @@ export class SimpleReactPyClient
340341
}
341342
this.lastActivityTime = Date.now();
342343
this.socket.current.send(JSON.stringify(message));
344+
345+
// Start response timeout for reconnecting grayout
346+
if (this.messageResponseTimeoutId) {
347+
window.clearTimeout(this.messageResponseTimeoutId);
348+
}
349+
this.messageResponseTimeoutId = window.setTimeout(() => {
350+
this.showReconnectingGrayout();
351+
}, 800);
343352
}
344353
}
345354

355+
protected handleIncoming(message: any): void {
356+
super.handleIncoming(message);
357+
}
358+
346359
idleTimeoutCheck(): void {
347360
if (!this.socket)
348361
return;
@@ -446,7 +459,15 @@ export class SimpleReactPyClient
446459
this.reconnect(onOpen, thisInterval, newRetriesRemaining, lastAttempt);
447460
}
448461
},
449-
onMessage: async ({ data }) => { this.lastActivityTime = Date.now(); this.handleIncoming(JSON.parse(data)) },
462+
onMessage: async ({ data }) => {
463+
this.lastActivityTime = Date.now();
464+
if (this.messageResponseTimeoutId) {
465+
window.clearTimeout(this.messageResponseTimeoutId);
466+
this.messageResponseTimeoutId = null;
467+
this.hideReconnectingGrayout();
468+
}
469+
this.handleIncoming(JSON.parse(data));
470+
},
450471
...this.reconnectOptions,
451472
});
452473
this.socketLoopIntervalId = window.setInterval(() => { this.socketLoop() }, this.socketLoopThrottle);

src/py/reactpy/reactpy/core/serve.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ async def _single_incoming_loop(
126126
# We need to fire and forget here so that we avoid waiting on the completion
127127
# of this event handler before receiving and running the next one.
128128
task_group.start_soon(layout.deliver, await recv())
129+
await send(AckMessage(type="ack"))
129130

130131

131132
class WebsocketServer:

src/py/reactpy/reactpy/core/types.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ class PingIntervalSetMessage(TypedDict):
269269
ping_interval: int
270270

271271

272+
class AckMessage(TypedDict):
273+
type: Literal["ack-message"]
274+
275+
272276
class Context(Protocol[_Type]):
273277
"""Returns a :class:`ContextProvider` component"""
274278

0 commit comments

Comments
 (0)