Skip to content

bare websockets - #6932

Open
benedikt-bartscher wants to merge 27 commits into
reflex-dev:mainfrom
benedikt-bartscher:make-sio-optional
Open

bare websockets#6932
benedikt-bartscher wants to merge 27 commits into
reflex-dev:mainfrom
benedikt-bartscher:make-sio-optional

Conversation

@benedikt-bartscher

@benedikt-bartscher benedikt-bartscher commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

saves ~11.6 KB gz / ~41 KB raw frontend size (a small js chunk replaces whole socketio)
dropped python deps: wsproto, simple-websocket, python-socketio, python-engineio, bidict
new benchmarks in test_event_transport.py show about 2x performance increase compared to socketio

also migrates AppHarness to granian for consistency. otherwise downstream tests using AppHarness still need uvicorn and wsproto/websockets

Review in cubic

@codspeed-hq

codspeed-hq Bot commented Aug 22, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 27 untouched benchmarks
🆕 4 new benchmarks
⏩ 8 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
🆕 Simulation test_transport_inbound_socketio N/A 7.9 ms N/A
🆕 Simulation test_transport_inbound_websocket N/A 4.3 ms N/A
🆕 Simulation test_transport_outbound_socketio N/A 17.3 ms N/A
🆕 Simulation test_transport_outbound_websocket N/A 8.6 ms N/A

Comparing benedikt-bartscher:make-sio-optional (d106af6) with main (6b44604)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR replaces the default Socket.IO transport with a lightweight plain-WebSocket protocol while retaining Socket.IO as an optional transport.

  • Adds browser and backend implementations for WebSocket framing, handshakes, heartbeats, reconnection, and event dispatch.
  • Makes Socket.IO and Uvicorn dependencies optional and updates Granian/Uvicorn launch behavior.
  • Hardens malformed-frame handling and fixes streamed-upload transaction-context reuse.
  • Adds transport benchmarks and unit/integration coverage.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
reflex/event_namespace.py Implements the plain-WebSocket event namespace and now closes malformed or invalid event streams without leaving the previously reported log-flood paths open.
packages/reflex-base/src/reflex_base/.templates/web/utils/helpers/websocket.js Adds the browser transport with framing, heartbeat monitoring, connection timeout handling, and documented human-readable durations.
packages/reflex-base/src/reflex_base/.templates/web/utils/state.js Selects the plain-WebSocket or optional Socket.IO client and adds connection/unmount lifecycle cleanup.
reflex/app.py Registers the direct WebSocket route by default and lazily initializes the optional Socket.IO transport.
reflex/utils/exec.py Updates backend launch paths and Uvicorn WebSocket sizing for the new transport configuration.
packages/reflex-base/src/reflex_base/event/processor/event_processor.py Forks the root event context for streaming deltas so unrelated events cannot attach to a completed future.
pyproject.toml Moves Socket.IO and Uvicorn support into optional extras and updates the Granian dependency.
tests/units/test_event_namespace.py Covers WebSocket protocol handling, byte-size enforcement, malformed payload closure, and event routing.

Reviews (21): Last reviewed commit: "Merge remote-tracking branch 'upstream/m..." | Re-trigger Greptile

Comment thread reflex/event_namespace.py Outdated
Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/helpers/websocket.js Outdated
@benedikt-bartscher
benedikt-bartscher marked this pull request as ready for review August 22, 2026 22:09
@benedikt-bartscher
benedikt-bartscher requested a review from a team as a code owner August 22, 2026 22:09

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 19 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread reflex/event_namespace.py
Comment thread reflex/event_namespace.py
Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/helpers/websocket.js Outdated
Comment thread reflex/utils/exec.py Outdated
Comment thread reflex/utils/exec.py Outdated
Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/state.js Outdated
@benedikt-bartscher
benedikt-bartscher marked this pull request as draft August 22, 2026 22:27
…ace, awaited disconnect cleanup; revert server-wide ws_max_size
Comment thread reflex/event_namespace.py Outdated
@benedikt-bartscher
benedikt-bartscher marked this pull request as ready for review August 22, 2026 22:46

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 17 files

Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.

Re-trigger cubic

Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/helpers/websocket.js Outdated
Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/state.js
Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/helpers/websocket.js Outdated
Comment thread reflex/event_namespace.py Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/reflex-base/src/reflex_base/.templates/web/utils/state.js
Comment thread reflex/event_namespace.py Outdated
Comment thread reflex/event_namespace.py Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread reflex/event_namespace.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 6 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread reflex/testing.py
Comment thread reflex/utils/exec.py
Comment thread pyproject.toml Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 6 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread reflex/testing.py Outdated
Comment thread tests/units/test_testing.py Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread reflex/testing.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread tests/units/test_testing.py
Comment thread reflex/testing.py Outdated
Comment thread reflex/event_namespace.py
Comment thread reflex/event_namespace.py

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread tests/units/test_event_namespace.py
Comment thread reflex/event_namespace.py
@abulvenz

Copy link
Copy Markdown
Contributor

I really like this lightweight approach 👍 .
One thing that is dropped, correct me if I see this wrong: under the hood socketio supports HTTP long-polling in case a websocket connection cannot be established (e.g. due to badly configured load balancers, reverse proxies or simply disabled client support). In most cases that should be fixed anyways on server side for performance reasons.

@benedikt-bartscher

Copy link
Copy Markdown
Contributor Author

I really like this lightweight approach 👍 . One thing that is dropped, correct me if I see this wrong: under the hood socketio supports HTTP long-polling in case a websocket connection cannot be established (e.g. due to badly configured load balancers, reverse proxies or simply disabled client support). In most cases that should be fixed anyways on server side for performance reasons.

Thanks 🙏

Yes, the new bare websockets implementation does not support http long-polling yet. However one could still choose the old socketio based transport to archive this. Also iirc longpolling was disabled by default anyway, i guess not a lot of users use it. If this is really needed i could add support to our bare websockets implementation as well.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants