Closed yivlad closed 4 days ago
Same issue on backend side (nest.js framework). Moreover, viem doesn't notify about socket disconnect/reconnect by logs, just looks like that websocket is just stuck without any reason.
Here is client creation code.
createPublicClient({
chain: Viem.utils.extractChain(CONFIG.CHAIN_ID),
transport: webSocket(CONFIG.RPC.WS, {
reconnect: true,
retryCount: Infinity,
retryDelay: 1000,
timeout: 1000
}),
})
I have the same problem, moreover i didn't find a way of being "notified" ( like an eventListener ) about the connection status.
Same problem for us, impossible to index via websocket, no disconnection errors and no automatic reconnection. This is really annoying, because we're going to have to listen via http and explode our alchemy quotas! Is a fix in the works?
Same problem for us, impossible to index via websocket, no disconnection errors and no automatic reconnection. This is really annoying, because we're going to have to listen via http and explode our alchemy quotas! Do you know if a fix is in the works?
You can increase the number of reconnect attempts (https://viem.sh/docs/clients/transports/websocket.html), but I don't see a way to be notified of the connection status..
the only way i can think of indexing all blocks with viem would be to go chunk by chunk using http requests.
in my case, it because the backend nginx timeout setting
when I subscribe a topic with indexed topics, it may have long time without response, if backend setting a max timeout, the socket will be closed, return code 1006('Abnormal Closure')
there are two way to resolve this issue:
verify all the CloseEvent code, apply onError logic first to reuse current reconnect logic. Yes, it will not trigger onerror like above timeout case
implement keepalive
I just implement the keep-alive feature: #2516
it will keep send ping
to ws server every 30s, and dev can set any value that less than your backend timeout setting, to make sure ws keep-alive
happy to receive some feedbacks
happy to receive some feedbacks
One thing I miss/couldn't find is a way to subscribe to connection events, like "connected," "disconnected," or "error," in order to make the application more self-aware.
During my initial tests with WS transport, I found that WS would disconnect and fail silently, and my application would stop.
i think either i'm missing something from the documentation or there is room for improvement.
happy to receive some feedbacks
One thing I miss/couldn't find is a way to subscribe to connection events, like "connected," "disconnected," or "error," in order to make the application more self-aware.
During my initial tests with WS transport, I found that WS would disconnect and fail silently, and my application would stop.
i think either i'm missing something from the documentation or there is room for improvement.
I think you can get the socket
first, and subscribe by yourself for advanced usage
const WS_URL = ''
const webSocketClient = createPublicClient({
chain: mainnet,
transport: webSocket(WS_URL)
})
const socketClient = await getWebSocketRpcClient(WS_URL)
const socket = socketClient.socket
getWebSocketRpcClient
interesting i didn't find docs for this function on viem website, but my VS CODE finds it.
thank you.
Fixed via 44281e8
^ amazing
Would be possible to also add documentation on how to listen for connection status on the websocket so services that rely on monitoring each block can recover quickly?
From @izayl i got the hint to look for getWebSocketRpcClient
but i havent' played with it yet.
thank you
Hey @jxom
It seems that the problem persists, we updated our staging environment yesterday and this morning the events are not caught... So the websocket connection must have closed... No errors on the watchContractEvent onError callback.
@flux0uz u can try with following code to verify the ws close reason first, see what's the code of close event
replace the ws_rpc_url
to yourselfs
if (publicClient.transport.type === 'webSocket') {
const client = await getWebSocketRpcClient(ws_rpc_url!)
const socket = client.socket
socket.addEventListener('close', (e) => {
console.error('websocket closed', e)
})
}
Thanks @izayl, no errors were detected on the socket "close" event. I've just realised that the problem is with the fallback([]). By removing the fallback on the public provider used to listen to events, everything works normally!
@jxom The fallback option for websocket transport is breaking the auto-reconnect and not throwing any errors.
Back to this issue! Another test this morning, listening to the sockets close (with @izayl code). No close log, and we don't receive any events. PublicProvider with a single websocket connection via Alchemy and no fallback.
Back to this issue! Another test this morning, listening to the sockets close (with @izayl code). No close log, and we don't receive any events. PublicProvider with a single websocket connection via Alchemy and no fallback.
double check your ABI, maybe has wrong order or missed indexed
Nop works correctly with http transport, but uses a ton of our Alchemy quota! What's more, it works perfectly for a while just after deployment - we wait about 1 day and then nothing is caught!
I'm now listening to message
on the dev environment, the first one is OK then I keep getting :
[Symbol(kData)]: '{"id":null,"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"}}'
i confirm. it doesn't work. please run a minimum reproducible for at least 2 hours before merging.
You might want to take a look at alchemy's ws implementation. tested it and its rock solid with no connection breaking. Looking at your fix why do use ping
if it's not supported by an json rpc api? I suggest using net_version
or chainId
like alchemy does
https://github.com/alchemyplatform/alchemy-sdk-js/blob/master/src/api/alchemy-websocket-provider.ts#L746-L757
rpc endpoints: https://docs.alchemy.com/reference/net-version https://www.quicknode.com/docs/ethereum/net_version
Check existing issues
Viem Version
2.13.1
Current Behavior
We use
webSocket
transport in our frontend app. After some period of inactivity browsers automatically close the web socket connections. When a user leaves the tab open and gets back after a while,webSocket
transport is unable to recover from the socketCLOSED
state and requests keep failing.Expected Behavior
webSocket
transport creates new connection in place of the closed one.Steps To Reproduce
Minimal reproducible example using only
viem
:In the provided code the second request fails because the web socket connection is closed.
Link to Minimal Reproducible Example
No response
Anything else?
No response