Files
backend/internal/pkg/ws/compress.go
lan 6bf87fec46
All checks were successful
Build Backend / build (push) Successful in 4m20s
Build Backend / build-docker (push) Successful in 1m7s
feat(chat): implement sequence pre-allocation, versioned sync, and push worker
Introduce several performance and synchronization enhancements:
- Implement `SeqBufferManager` to allow sequence number pre-allocation via Redis Lua scripts, reducing atomic increment overhead.
- Add `PushWorker` to handle asynchronous message pushing using Redis Streams.
- Implement incremental conversation synchronization via `ConversationVersionLog` to allow clients to fetch only recent changes.
- Add support for Gzip compression in WebSocket communications to reduce bandwidth usage.
- Update dependency injection and configuration to support these new components.
2026-05-17 23:38:04 +08:00

71 lines
1.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package ws
import (
"bytes"
"compress/gzip"
"io"
"sync"
)
const gzipMagicByte = 0x1F
// Compressor 管理 gzip Writer/Reader 的 sync.Pool 复用
type Compressor struct {
writerPool sync.Pool
readerPool sync.Pool
level int
}
// NewCompressor 创建 Compressorlevel: gzip.DefaultCompression/BestSpeed/BestCompression 等)
func NewCompressor(level int) *Compressor {
return &Compressor{
level: level,
writerPool: sync.Pool{
New: func() any {
w, _ := gzip.NewWriterLevel(io.Discard, level)
return w
},
},
readerPool: sync.Pool{
New: func() any { return new(gzip.Reader) },
},
}
}
// Compress 压缩数据,返回 gzip 字节
func (c *Compressor) Compress(data []byte) ([]byte, error) {
buf := &bytes.Buffer{}
w := c.writerPool.Get().(*gzip.Writer)
w.Reset(buf)
if _, err := w.Write(data); err != nil {
c.writerPool.Put(w)
return nil, err
}
if err := w.Close(); err != nil {
c.writerPool.Put(w)
return nil, err
}
c.writerPool.Put(w)
return buf.Bytes(), nil
}
// Decompress 解压 gzip 数据
func (c *Compressor) Decompress(data []byte) ([]byte, error) {
r := c.readerPool.Get().(*gzip.Reader)
if err := r.Reset(bytes.NewReader(data)); err != nil {
c.readerPool.Put(r)
return nil, err
}
out, err := io.ReadAll(r)
r.Close()
c.readerPool.Put(r)
return out, err
}
// IsCompressed 检查数据是否以 gzip magic byte 开头
func IsCompressed(data []byte) bool {
return len(data) > 0 && data[0] == gzipMagicByte
}
// DefaultCompressor 全局默认压缩器gzip.DefaultCompression = level 6
var DefaultCompressor = NewCompressor(gzip.DefaultCompression)