zsocket is a lightweight, zero-dependency, high-performance WebSocket & Event Engine library for Go. It features full RFC 6455 and RFC 7692 (permessage-deflate) compliance, an optimized low-level WebSocket engine, and a Socket.IO-style event-driven messaging module with Acknowledgements (ACK) and Room support.
Module:
github.com/aminofox/zsocket
- 🚀 Dual Engine Architecture:
- Core WebSocket: Low-level, high-throughput RFC 6455 engine with custom dialing, hijacking, streaming readers/writers, and JSON helpers.
- Socket.IO Layer (
zsocket/socketio): High-level event-driven protocol withOn(),Emit(),EmitWithAck(), namespaces, and room broadcasting.
- ⚡ High Performance & Zero-Alloc Optimizations:
- Fast 64-bit word-at-a-time (SIMD-style) XOR payload unmasking.
- Reader/Writer buffer pooling via
sync.Pool. - Non-blocking room mutexes to eliminate broadcast lock contention.
- 🛡️ Security & Hardened RFC Compliance:
- Strict UTF-8 validation for text frames and close reasons (RFC 6455 §8.1).
- Protection against 64-bit frame extended length MSB exploits (DoS prevention).
- Cumulative multi-fragment
ReadLimitenforcement to prevent memory exhaustion. - Proper HTTP error status responses (
405,400,403) prior to connection hijacking.
- 🗜️ RFC 7692 Deflate Compression: Full browser-compatible
permessage-deflatewith\x00\x00\xff\xffsuffix stripping and pooled flate compressor instances. - 🔌 Rich Ecosystem: Includes built-in middleware for Authentication, Rate Limiting, Metrics, and a Pub/Sub adapter for Redis horizontal scaling.
go get github.com/aminofox/zsocketBuild event-driven real-time applications effortlessly with the Node.js Socket.IO-like API:
package main
import (
"fmt"
"log"
"net/http"
"github.com/aminofox/zsocket"
"github.com/aminofox/zsocket/socketio"
)
func main() {
server := socketio.NewServer(zsocket.DefaultConfig())
server.OnConnection(func(s *socketio.Socket) {
fmt.Println("Client connected:", s.ID())
// Join a room
s.Join("lobby")
// Register event handler with automatic ACK reply
s.On("chat_message", func(data []byte) (any, error) {
log.Printf("Received message: %s", string(data))
// Broadcast to everyone in "lobby" except current client
s.BroadcastTo("lobby").Emit("new_message", string(data))
// Return response to trigger client ACK callback
return map[string]string{"status": "delivered"}, nil
})
})
http.Handle("/socket.io/", server)
log.Println("Socket.IO server listening on :8080...")
log.Fatal(http.ListenAndServe(":8080", nil))
}package main
import (
"context"
"fmt"
"log"
"time"
"github.com/aminofox/zsocket/socketio"
)
func main() {
client, err := socketio.DialSocket("ws://localhost:8080/socket.io/", nil)
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer client.Close()
// Listen for events
client.On("new_message", func(data []byte) (any, error) {
fmt.Println("Broadcast message:", string(data))
return nil, nil
})
// Emit event and wait for ACK response
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
ackResp, err := client.EmitWithAck(ctx, "chat_message", "Hello Socket.IO World!")
if err != nil {
log.Fatalf("ACK failed: %v", err)
}
fmt.Println("Server ACK:", string(ackResp))
}If you prefer standard low-level WebSocket frames:
package main
import (
"context"
"log"
"net/http"
"github.com/aminofox/zsocket"
)
func main() {
cfg := zsocket.DefaultConfig()
upgrader := zsocket.Upgrader{Config: cfg}
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Printf("Upgrade error: %v", err)
return
}
defer conn.Close(zsocket.CloseNormalClosure, "server shutdown")
ctx := context.Background()
for {
mt, msg, err := conn.Read(ctx)
if err != nil {
log.Printf("Read error: %v", err)
return
}
// Echo message back
if err := conn.Write(ctx, mt, msg); err != nil {
return
}
}
})
log.Fatal(http.ListenAndServe(":8080", nil))
}Config allows fine-tuning security boundaries and performance parameters:
cfg := zsocket.DefaultConfig()
// Security & Handshake
cfg.HandshakeTimeout = 10 * time.Second
cfg.ReadLimit = 16 << 20 // 16 MiB max message size
cfg.CheckOrigin = zsocket.IsSameOrigin // Same-Origin enforcement
// Keepalive & Deadlines
cfg.PingInterval = 30 * time.Second
cfg.PongWait = 15 * time.Second
cfg.WriteTimeout = 10 * time.Second
// Compression (RFC 7692)
cfg.EnableCompression = true
cfg.CompressionLevel = flate.BestSpeed// Custom Origin validation
cfg.CheckOrigin = func(r *http.Request) bool {
origin := r.Header.Get("Origin")
return origin == "https://mydomain.com"
}- Authentication:
middleware.Auth(...) - Rate Limiting:
middleware.NewRateLimiter(...) - Metrics: Track connection counters and message volume.
To scale WebSocket rooms horizontally across multiple server instances, use hub.RedisHub:
import "github.com/aminofox/zsocket/hub"
// Wrap pub/sub client to synchronize room broadcasts across nodes
redisHub := hub.NewRedisHub(pubsubClient)Distributed under the MIT License.