Explicit reconnect should rejoin the channels.
Doing an explicit reconnect on existing open connection using:
socket.disconnect()
socket.connect()
or
socket.reconnectTimer.scheduleTimeout()
does not rejoin the channels. Instead we start getting reason: "unmatched topic" errors.
We use this to try to switch from LongPoll connection to WebSocket connection.
Basically what we do is (coffeescript):
startAvoidLongPollWorker = (socket) ->
work = ->
# Avoid changing transports and interfering with the reconnection logic
# when we don't have an established connection and the reconnection might
# already be in progress
return if socket.connectionState() != 'open'
# Return if the user is already not using LongPoll
return if socket.transport != Phoenix.LongPoll
newTransport = findNewTransport(socket.transport)
# Return if the new transport is the same
return if socket.transport == newTransport
# Change socket transport and schedule a reconnect
socket.transport = newTransport
socket.reconnectTimer.scheduleTimeout()
setInterval(work, AVOID_LONGPOLL_WORKER_INTERVAL_IN_MS)
As a workaround we currently did:
socket.onOpen ->
# Do channel rejoin in next event loop, otherwise it's too soon and
# doesn't work.
channels = socket.channels
setTimeout(->
channels.forEach((channel) ->
channel.rejoinTimer.scheduleTimeout()
)
)
socket.reconnectTimer.scheduleTimeout() these are private APIs so to avoid confusion, can you confirm if the following alone triggers this issue:
socket.disconnect()
socket.connect()
Do things rejoin in this case?
They don't. The result is same. There's no rejoin and I start getting unmatched topic errors.
@indrekj Based on your knowledge, is this still a current bug and do you think this should be fixed by the library (and not userland code)? If so, I can startg taking a look...
@snewcomer definitely something we should handle on our side. Channels rejoins happen automatically on connection recovery, but sounds like there is a bug here when disconnect => reconnect in the same event loop. Can you take a look? Thanks!
https://github.com/phoenixframework/phoenix/pull/3665/files#r375649649
Hi @indrekj. My comment in your PR relates to the test context. So, in a non-test environment, it would be great to hear what happens if you connect in the next macroTask...
socket.disconnect();
setTimeout(() => {
socket.connect();
}, 100);
Is "onConnClose" eventually called (w/ master or your latest version of phoenix)?
Is "onConnClose" eventually called
It is not.
馃憤 Seeing the same thing in a running app.
Although, I'm unable to reproduce reason: "unmatched topic"calling disconnect and connect sequentially in a very simple case. I hate to ask b/c you have put in a bunch of great work, but is this something you can provide in a demo app?
@indrekj I think we have it fixed! Would love to hear what you think about #3708!!




Most helpful comment
@snewcomer definitely something we should handle on our side. Channels rejoins happen automatically on connection recovery, but sounds like there is a bug here when disconnect => reconnect in the same event loop. Can you take a look? Thanks!