Skip to content

Bugfix/6710/fix multiple websockets - #6737

Open
mahibi wants to merge 1 commit into
masterfrom
bugfix/6710/fixMultipleWebsockets
Open

mahibi wants to merge 1 commit into
masterfrom
bugfix/6710/fixMultipleWebsockets

Conversation

@mahibi

@mahibi mahibi commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator

fix #6710

Root cause, two parts:

  • WebSocketConnectionHelper.getExternalSignalingInstanceForServer() only reused the cached WebSocketInstance for a user when isConnected() == true. The ping interval added in fix(call): detect dead signaling WebSocket connections via ping interval #6543 makes the connection cycle through a brief
    disconnected state every 30-60s by design; any caller asking for the socket during that window got a second, independent instance instead of the existing one, orphaning the first — which kept retrying itself,
    unsupervised, in the background.

  • Within a single WebSocketInstance, nothing cancelled an in-flight socket before starting a new one, and a stale/already-superseded socket's failure could still trigger another reconnect of the current one — letting one
    real disconnect cascade into several parallel sockets.

Fix:
The Helper now always reuses an existing instance for a user regardless of connection state (it manages its own reconnects). restartWebSocket() now tracks the new socket before tearing down the old one, and closeWebSocket() ignores callbacks from a socket that's already been superseded.

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔖 Capability is checked or not needed
  • 🔙 Backport requests are created or not needed: /backport to stable-xx.x
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@mahibi mahibi added this to the 25.1.0 milestone Sep 20, 2026
@mahibi mahibi self-assigned this Sep 20, 2026
WebSocketConnectionHelper only reused the cached WebSocketInstance for a
user while it reported isConnected() == true. Since the ping interval
added in #6543 makes the connection cycle through a brief disconnected
state every 30-60s by design, any caller (ChatActivity, CallActivity,
WebsocketConnectionsWorker) asking for the instance during that window
got handed a brand new WebSocketInstance instead, orphaning the old one
which kept retrying unsupervised in the background.

Within a single instance, restartWebSocket() could also be triggered
concurrently (from sendMessage, processErrorMessage, closeWebSocket)
without cancelling any socket already in flight, and a stale/superseded
socket's failure would still force a reconnect of the current one. Both
issues together produced the "5-13 parallel sockets" / repeated
"Closing previous client ... for session X" churn from #6710.

Fixes #6710.

Assisted-by: Claude Code:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
@mahibi
mahibi force-pushed the bugfix/6710/fixMultipleWebsockets branch from 8021b33 to 2295a42 Compare September 20, 2026 16:41
@mahibi
mahibi marked this pull request as ready for review September 20, 2026 16:41
@mahibi

mahibi commented Sep 20, 2026

Copy link
Copy Markdown
Collaborator Author

/backport to stable-25.0.x

@mahibi mahibi added the 3. to review Waiting for reviews label Sep 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📱 QA build

Download app-qa-debug.apk
QR code Open the QR code for this download
Commit 2295a42
Version 6737
Available until 7 days after this build

The QA build installs alongside a released Nextcloud app, so you can keep
using your existing install while testing.

Downloading the file requires a GitHub account, so open this link on the
device you want to test on, or transfer the APK to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

25.0.0: app opens many parallel signaling websockets that die after exactly 60 s, call drops and rejoins every minute

1 participant