Skip to content

Conversation

@acooks
Copy link
Owner

@acooks acooks commented Dec 9, 2025

Replace libwebsockets permessage-deflate extension with application-level deflate compression using a preset dictionary optimized for JitterTrap JSON messages.

Benefits over permessage-deflate:

  • 20-40% smaller than gzip for typical messages (dictionary provides immediate context for common JSON keys, message types, IP prefixes)
  • Works regardless of libwebsockets build configuration
  • Lower compression threshold (128 bytes vs typical 256)

Compression results with dictionary:

  • Stats messages: 29% of original (vs 50% with gzip)
  • Toptalk 5 flows: 22% of original (vs 31% with gzip)
  • Toptalk 20 flows: 12% of original (vs 15% with gzip)

Implementation:

  • Server: ws_compress.c uses zlib raw deflate with 662-byte dictionary
  • Client: pako.js inflateRaw with matching dictionary
  • Messages >128 bytes compressed and sent as binary WebSocket frames
  • Smaller messages sent uncompressed as text (backward compatible)

Security:

  • 64KB max decompression size limit (prevents decompression bombs)
  • Graceful fallback if decompression fails

Debug helpers available in browser console:

  • JT.ws.decode(data) - decode compressed message
  • JT.ws.dictionary - view dictionary string

🤖 Generated with Claude Code

…nary

Replace libwebsockets permessage-deflate extension with application-level
deflate compression using a preset dictionary optimized for JitterTrap
JSON messages.

Benefits over permessage-deflate:
- 20-40% smaller than gzip for typical messages (dictionary provides
  immediate context for common JSON keys, message types, IP prefixes)
- Works regardless of libwebsockets build configuration
- Lower compression threshold (128 bytes vs typical 256)

Compression results with dictionary:
- Stats messages: 29% of original (vs 50% with gzip)
- Toptalk 5 flows: 22% of original (vs 31% with gzip)
- Toptalk 20 flows: 12% of original (vs 15% with gzip)

Implementation:
- Server: ws_compress.c uses zlib raw deflate with 662-byte dictionary
- Client: pako.js inflateRaw with matching dictionary
- Messages >128 bytes compressed and sent as binary WebSocket frames
- Smaller messages sent uncompressed as text (backward compatible)

Security:
- 64KB max decompression size limit (prevents decompression bombs)
- Graceful fallback if decompression fails

Debug helpers available in browser console:
- JT.ws.decode(data) - decode compressed message
- JT.ws.dictionary - view dictionary string

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@acooks acooks merged commit c588418 into master Dec 9, 2025
2 checks passed
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