-
-
Notifications
You must be signed in to change notification settings - Fork 391
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
On websocket connection closed, auto-reconnect connects the websocket again and tries to rejoin channels but this doesn't work, the channel stays closed:
2025-11-16 16:41:21,029 - INFO - channel=ChannelStates.JOINED
2025-11-16 16:41:21,030 - INFO - send: {"event":"heartbeat","payload":{},"topic":"phoenix","ref":null,"join_ref":null}
2025-11-16 16:41:21,067 - INFO - receive: '{"ref":null,"event":"phx_reply","payload":{"status":"ok","response":{}},"topic":"phoenix"}'
2025-11-16 16:41:21,068 - INFO - parsed message as event=<ChannelEvents.reply: 'phx_reply'> topic='phoenix' payload=SuccessReplyMessage(status='ok', response=ReplyPostgresChanges(postgres_changes=None)) ref=None
2025-11-16 16:41:27,470 - ERROR - WebSocket connection closed with code: 1006, reason:
2025-11-16 16:41:27,470 - INFO - Initiating auto-reconnect sequence...
2025-11-16 16:41:27,470 - INFO - Attempting to connect to WebSocket at wss://xxx.supabase.co/realtime/v1/websocket?apikey=sb_secret_xxx
2025-11-16 16:41:27,685 - INFO - WebSocket connection established successfully
2025-11-16 16:41:27,685 - INFO - Rejoining channel after reconnection: realtime:gateways
2025-11-16 16:41:27,690 - INFO - send: {"event":"phx_leave","payload":{},"topic":"realtime:gateways","ref":"2","join_ref":null}
2025-11-16 16:41:27,692 - INFO - send: {"event":"phx_join","payload":{"config":{"broadcast":null,"presence":{"key":"","enabled":false},"private":true,"postgres_changes":[]},"access_token":"sb_secret_xxx"},"topic":"realtime:gateways","ref":"3","join_ref":null}
2025-11-16 16:41:27,692 - INFO - send: {"event":"heartbeat","payload":{},"topic":"phoenix","ref":null,"join_ref":null}
2025-11-16 16:41:27,712 - INFO - receive: '{"ref":"2","event":"phx_reply","payload":{"status":"ok","response":{}},"topic":"realtime:gateways"}'
2025-11-16 16:41:27,713 - INFO - parsed message as event=<ChannelEvents.reply: 'phx_reply'> topic='realtime:gateways' payload=SuccessReplyMessage(status='ok', response=ReplyPostgresChanges(postgres_changes=None)) ref='2'
2025-11-16 16:41:27,713 - INFO - realtime:gateways : event=<ChannelEvents.reply: 'phx_reply'> topic='realtime:gateways' payload=SuccessReplyMessage(status='ok', response=ReplyPostgresChanges(postgres_changes=None)) ref='2'
2025-11-16 16:41:27,713 - INFO - channel realtime:gateways leave
2025-11-16 16:41:27,713 - INFO - channel realtime:gateways closed
2025-11-16 16:41:27,821 - INFO - receive: '{"ref":"3","event":"phx_reply","payload":{"status":"ok","response":{"postgres_changes":[]}},"topic":"realtime:gateways"}'
2025-11-16 16:41:27,827 - INFO - parsed message as event=<ChannelEvents.reply: 'phx_reply'> topic='realtime:gateways' payload=SuccessReplyMessage(status='ok', response=ReplyPostgresChanges(postgres_changes=[])) ref='3'
2025-11-16 16:41:27,827 - INFO - receive: '{"ref":null,"event":"phx_reply","payload":{"status":"ok","response":{}},"topic":"phoenix"}'
2025-11-16 16:41:27,827 - INFO - parsed message as event=<ChannelEvents.reply: 'phx_reply'> topic='phoenix' payload=SuccessReplyMessage(status='ok', response=ReplyPostgresChanges(postgres_changes=None)) ref=None
2025-11-16 16:41:37,702 - WARNING - subscription status=RealtimeSubscribeStates.TIMED_OUT err=None
2025-11-16 16:41:46,039 - INFO - channel=ChannelStates.CLOSED
2025-11-16 16:41:52,698 - INFO - send: {"event":"heartbeat","payload":{},"topic":"phoenix","ref":null,"join_ref":null}
2025-11-16 16:41:52,737 - INFO - receive: '{"ref":null,"event":"phx_reply","payload":{"status":"ok","response":{}},"topic":"phoenix"}'
2025-11-16 16:41:52,737 - INFO - parsed message as event=<ChannelEvents.reply: 'phx_reply'> topic='phoenix' payload=SuccessReplyMessage(status='ok', response=ReplyPostgresChanges(postgres_changes=None)) ref=None
2025-11-16 16:42:11,044 - INFO - channel=ChannelStates.CLOSED
I suspect this might be linked to the fact that the phx_leave and phx_join messages are sent consecutively without waiting for the first one reply.
Reproduction
import asyncio
import logging
from supabase.client import AsyncClient
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
async def main(args):
client = AsyncClient(url, key)
await client.realtime.connect()
channel = client.channel("test", {"config": {"private": True}})
def on_subscribe(status, err):
logging.warning(f"subscription status={status} err={err}")
def on_message(msg):
logging.info(f"{msg['event']}")
await (channel.on_broadcast("INSERT", on_message).subscribe(on_subscribe))
while True:
logging.info(f"channel={channel.state}")
await asyncio.sleep(25)
asyncio.run(main(args))Steps to reproduce
Run the snippet above and wait for a disconnection (or provoke it)
Library affected
realtime
Library version
supabase 2.24.0
Python version
python 3.12.3
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working