Files
go-omni/ws/config.go

84 lines
2.8 KiB
Go

package ws
import (
"fmt"
"time"
)
// SessionConfig bounds connection memory and I/O. Zero fields use defaults;
// DisableHeartbeat explicitly disables automatic ping/pong deadlines.
type SessionConfig struct {
MaxMessageBytes int64 `json:"maxMessageBytes"`
ReadQueueSize int `json:"readQueueSize"`
ReadQueueBytes int64 `json:"readQueueBytes"`
WriteQueueSize int `json:"writeQueueSize"`
WriteQueueBytes int64 `json:"writeQueueBytes"`
WriteTimeout time.Duration `json:"writeTimeout"`
PingInterval time.Duration `json:"pingInterval"`
PongTimeout time.Duration `json:"pongTimeout"`
CloseTimeout time.Duration `json:"closeTimeout"`
DisableHeartbeat bool `json:"disableHeartbeat"`
}
func DefaultSessionConfig() SessionConfig {
return SessionConfig{MaxMessageBytes: 1 << 20, ReadQueueSize: 64, ReadQueueBytes: 4 << 20,
WriteQueueSize: 64, WriteQueueBytes: 4 << 20, WriteTimeout: 10 * time.Second,
PingInterval: 30 * time.Second, PongTimeout: 60 * time.Second, CloseTimeout: 5 * time.Second}
}
func (c SessionConfig) defaults() SessionConfig {
d := DefaultSessionConfig()
if c.MaxMessageBytes == 0 {
c.MaxMessageBytes = d.MaxMessageBytes
}
if c.ReadQueueSize == 0 {
c.ReadQueueSize = d.ReadQueueSize
}
if c.ReadQueueBytes == 0 {
c.ReadQueueBytes = d.ReadQueueBytes
}
if c.WriteQueueSize == 0 {
c.WriteQueueSize = d.WriteQueueSize
}
if c.WriteQueueBytes == 0 {
c.WriteQueueBytes = d.WriteQueueBytes
}
if c.WriteTimeout == 0 {
c.WriteTimeout = d.WriteTimeout
}
if c.PingInterval == 0 {
c.PingInterval = d.PingInterval
}
if c.PongTimeout == 0 {
c.PongTimeout = d.PongTimeout
}
if c.CloseTimeout == 0 {
c.CloseTimeout = d.CloseTimeout
}
return c
}
func (c SessionConfig) Validate() error {
if c.MaxMessageBytes < 0 || c.MaxMessageBytes > 1<<30 || c.ReadQueueSize < 0 || c.ReadQueueSize > 65536 || c.ReadQueueBytes < 0 || c.ReadQueueBytes > 1<<30 || c.WriteQueueSize < 0 || c.WriteQueueSize > 65536 || c.WriteQueueBytes < 0 || c.WriteQueueBytes > 1<<30 {
return fmt.Errorf("ws: message and queue limits must be nonnegative and bounded")
}
if c.WriteTimeout < 0 || c.PingInterval < 0 || c.PongTimeout < 0 || c.CloseTimeout < 0 {
return fmt.Errorf("ws: timeouts must be nonnegative")
}
if c.WriteTimeout > 24*time.Hour || c.PingInterval > 24*time.Hour || c.PongTimeout > 24*time.Hour || c.CloseTimeout > 24*time.Hour {
return fmt.Errorf("ws: timeout exceeds 24 hours")
}
c = c.defaults()
if !c.DisableHeartbeat && c.PongTimeout <= c.PingInterval {
return fmt.Errorf("ws: pongTimeout must exceed pingInterval")
}
return nil
}
func normalizeSessionConfig(c SessionConfig) (SessionConfig, error) {
if err := c.Validate(); err != nil {
return SessionConfig{}, err
}
return c.defaults(), nil
}