package main
import (
"context"
"encoding/json"
"errors"
"log"
"net/http"
"github.com/go-mizu/mizu"
"github.com/go-mizu/mizu/live"
)
var server *live.Server
func main() {
server = live.New(live.Options{
// Authentication
OnAuth: func(ctx context.Context, r *http.Request) (any, error) {
token := r.URL.Query().Get("token")
userID, err := validateToken(token)
if err != nil {
return nil, err
}
return userID, nil
},
// Message handling
OnMessage: func(ctx context.Context, s *live.Session, topic string, data []byte) {
handleMessage(s, topic, data)
},
// Cleanup on disconnect
OnClose: func(s *live.Session, err error) {
userID := s.Value().(string)
log.Printf("User %s disconnected", userID)
server.Publish("presence", []byte(`{"type":"leave","user":"`+userID+`"}`))
},
// Limits
QueueSize: 512,
ReadLimit: 64 * 1024,
// Origins
Origins: []string{"https://myapp.com"},
})
app := mizu.New()
app.Get("/ws", mizu.Compat(server.Handler()))
app.Listen(":8080")
}
func handleMessage(s *live.Session, topic string, data []byte) {
userID := s.Value().(string)
switch topic {
case "subscribe":
var req struct{ Topic string `json:"topic"` }
json.Unmarshal(data, &req)
// Validate subscription
if canSubscribe(userID, req.Topic) {
server.Subscribe(s, req.Topic)
}
case "unsubscribe":
var req struct{ Topic string `json:"topic"` }
json.Unmarshal(data, &req)
server.Unsubscribe(s, req.Topic)
case "chat":
// Broadcast chat message
msg, _ := json.Marshal(map[string]any{
"user": userID,
"data": json.RawMessage(data),
})
server.Publish("chat:general", msg)
}
}