Open pkpk2 opened 1 year ago
i've got the same problem too, did you manage to create a workaround?
i've got the same problem too, did you manage to create a workaround?
@msmaiaa Yes, i created a workaround:
@pkpk2 Does your solution work with the shared
option? I've been brainstorming a couple of ideas for handling this situation, but have not come up with one that works efficiently where there are multiple subscribers.
@pkpk2 Hi, what do you mean by useRef buffer? Could you elaborate more?
@melihcoban he likely collects the messages in a useRef array and then retrieves them (and empties the array) in a throttled/debounced manner.
@robtaussig I see, I kind of have the same issue with the original post, however like you said using shared in the websocket complicates things.
@pkpk2 Does your solution work with the shared option? I've been brainstorming a couple of ideas for handling this situation, but have not come up with one that works efficiently where there are multiple subscribers.
@robtaussig I have not tried shared unfortunately. Can not confirm, but i can try in a few days.
@melihcoban he likely collects the messages in a useRef array and then retrieves them (and empties the array) in a throttled/debounced manner.
Correct. useRef is used to do the data buffering without triggering the components re rendering on each event.
My implementation as an example - I dequeue 1 message each time so as not to flood the state updates as I can get many messages in short bursts.
// Create a ref array so we don't trigger rendering on mutation
const messageList = useRef<TMessage[]>([]);
// Put messages into a buffer for later processing
const onMessageCallback = (event: MessageEvent<string>) => {
if (event.data !== 'undefined') {
const message: TMessage = JSON.parse(event.data);
messageList.current.push(message);
}
};
useWebSocket(`${EVENTS_ROOT}/session/${id}`, {
onMessage: onMessageCallback,
});
useEffect(() => {
const t = setInterval(() => {
const updateMessage = messageList.current.shift();
if (updateMessage !== undefined) {
// Do something with your message here
}
}
}, 200);
// Clean up
return () => {
clearInterval(t);
};
}, [id]);
I run into a situation when useEffect invocation was skipped during a higher number of incoming events
two scenarios to compare:
websocket receives 30 events with a delay 1 second between them. useEffect/lastMessage combination was able to process all of them.
websocket receives 30 events without the delay, useEffect/lastMessage have been invoked only for a small subset of the events, so most of the events had been skipped essentially from the main execution path.
In both cases onMessage handler showed all expected events had been received.
Any thoughts how this situation can be handled without doing a custom onMessage and buffering? Should the framework do the proper buffering and return a list of events since the last access vs. just the last one?