### Programmatic Configuration Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/configuration.md Go code demonstrating how to programmatically configure and start the Mochi MQTT server. This includes setting up listeners, hooks, and server options. ```go package main import ( mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/listeners" "github.com/mochi-mqtt/server/v2/hooks/auth" "log" ) func main() { // Create server with custom options server := mqtt.New(&mqtt.Options{ Capabilities: &mqtt.Capabilities{ MaximumClients: 10000, MaximumMessageExpiryInterval: 86400, MaximumClientWritesPending: 8192, ReceiveMaximum: 1024, MaximumQos: 2, RetainAvailable: 1, WildcardSubAvailable: 1, }, ClientNetWriteBufferSize: 4096, ClientNetReadBufferSize: 4096, SysTopicResendInterval: 10, InlineClient: true, }) // Add TCP listener tcp := listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", }) if err := server.AddListener(tcp); err != nil { log.Fatal(err) } // Add WebSocket listener ws := listeners.NewWebsocket(listeners.Config{ ID: "ws1", Address: ":1882", }) if err := server.AddListener(ws); err != nil { log.Fatal(err) } // Add stats dashboard stats := listeners.NewHTTPStats(listeners.Config{ ID: "stats", Address: ":8080", }, server.Info) if err := server.AddListener(stats); err != nil { log.Fatal(err) } // Add allow-all auth (development only) if err := server.AddHook(new(auth.AllowHook), nil); err != nil { log.Fatal(err) } // Start the server if err := server.Serve(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Basic Storage Hook Setup Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/storage-hooks.md Demonstrates the basic setup for using a storage hook (BadgerDB) with the Mochi MQTT server, including adding listeners and starting the server. ```go server := mqtt.New(nil) // Add storage hook err := server.AddHook(new(badger.Hook), &badger.Options{ Path: "./data", }) if err != nil { log.Fatal(err) } // Add listeners server.AddListener(listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", })) // Start server err = server.Serve() // On startup, the server will: // 1. Load stored clients, subscriptions, and inflight messages // 2. Restore client sessions // 3. Reconnect stored subscriptions // 4. Resume delivery of inflight messages ``` -------------------------------- ### Start Mochi MQTT Server Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Demonstrates how to start the Mochi MQTT server and handle potential errors. Includes options for blocking or background execution. ```go // Start and block if err := server.Serve(); err != nil { log.Fatal(err) } // Start in background go func() { if err := server.Serve(); err != nil { log.Fatal(err) } }() ``` -------------------------------- ### Error Handling: Comprehensive Server Setup Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/errors.md Presents a comprehensive error handling pattern for server setup, including adding listeners and hooks, and starting the server. It uses `fmt.Errorf` with `%w` to wrap underlying errors, preserving context. ```go func setupServer() error { server := mqtt.New(nil) tcp := listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", }) if err := server.AddListener(tcp); err != nil { return fmt.Errorf("failed to add listener: %w", err) } if err := server.AddHook(new(auth.AllowHook), nil); err != nil { return fmt.Errorf("failed to add auth hook: %w", err) } if err := server.Serve(); err != nil { return fmt.Errorf("server error: %w", err) } return nil } ``` -------------------------------- ### Minimal MQTT Server Setup Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/README.md This snippet shows the most basic setup for an MQTT server using TCP listener and allowing all connections. It's suitable for development environments. ```go package main import ( "log" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { // Create server server := mqtt.New(nil) // Add TCP listener tcp := listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", }) server.AddListener(tcp) // Allow all connections (development only) server.AddHook(new(auth.AllowHook), nil) // Start server if err := server.Serve(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Full Mochi MQTT Server Example with BadgerDB Storage Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/storage-hooks.md A complete example demonstrating how to set up a Mochi MQTT server with the BadgerDB storage hook, a TCP listener, and an authentication hook. ```go package main import ( "log" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/hooks/storage/badger" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { server := mqtt.New(nil) // Add persistent storage err := server.AddHook(new(badger.Hook), &badger.Options{ Path: "/var/mqtt/data", }) if err != nil { log.Fatal(err) } // Add TCP listener tcp := listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", }) server.AddListener(tcp) // Add auth hook server.AddHook(new(auth.AllowHook), nil) if err := server.Serve(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Complete Mochi MQTT Server Setup Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md This Go code demonstrates a full Mochi MQTT server setup. It includes adding TCP, WebSocket, HTTP stats, and health check listeners. It also adds a development-only allow-all authentication hook and starts the server in the background. The server gracefully shuts down upon receiving an interrupt signal. ```go package main import ( "crypto/tls" "log" "os" "os/signal" "syscall" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { // Create server server := mqtt.New(&mqtt.Options{ InlineClient: true, }) // Add TCP listener tcp := listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", }) if err := server.AddListener(tcp); err != nil { log.Fatal(err) } // Add WebSocket listener ws := listeners.NewWebsocket(listeners.Config{ ID: "ws1", Address: ":1882", }) if err := server.AddListener(ws); err != nil { log.Fatal(err) } // Add HTTP stats endpoint stats := listeners.NewHTTPStats(listeners.Config{ ID: "stats", Address: ":8080", }, server.Info) if err := server.AddListener(stats); err != nil { log.Fatal(err) } // Add health check endpoint healthcheck := listeners.NewHTTPHealthCheck(listeners.Config{ ID: "health", Address: ":8081", }) if err := server.AddListener(healthcheck); err != nil { log.Fatal(err) } // Add allow-all auth (development only) if err := server.AddHook(new(auth.AllowHook), nil); err != nil { log.Fatal(err) } // Start server in background go func() { if err := server.Serve(); err != nil { log.Fatal(err) } }() // Wait for interrupt signal sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) <-sigs server.Close() } ``` -------------------------------- ### Start MQTT Server Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/server.md Starts the MQTT server's event loops for client connections, system topics, and hooks. Returns an error if the server fails to start. ```go server := mqtt.New(nil) // Add listeners and hooks... err := server.Serve() if err != nil { log.Fatal(err) } // Server is now running and accepting connections ``` -------------------------------- ### Example AuthRules Configuration Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/auth-hooks.md Provides an example of how to configure a slice of AuthRules. Rules are evaluated in order, and the first match determines the connection outcome. A final rule with `Allow: false` acts as a catch-all to deny any connections not explicitly allowed. ```go auth.AuthRules{ {Client: "broker", Password: "secret", Allow: true}, {Username: "alice", Password: "pass123", Allow: true}, {Username: "bob", Password: "pass456", Allow: true}, {Remote: "192.168.1.*:*", Allow: true}, // Local network {Remote: "localhost:*", Allow: true}, // Localhost {Allow: false}, // Deny all others (default) } ``` -------------------------------- ### YAML Configuration Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/configuration.md Example of a complete YAML configuration file for the Mochi MQTT server. This includes listener definitions, hook configurations, and various server options. ```yaml listeners: - type: "tcp" id: "tcp1" address: ":1883" - type: "ws" id: "ws1" address: ":1882" - type: "sysinfo" id: "stats" address: ":8080" hooks: auth: allow_all: true options: inline_client: true sys_topic_resend_interval: 10 capabilities: maximum_clients: 10000 maximum_message_expiry_interval: 86400 maximum_qos: 2 receive_maximum: 1024 maximum_inflight: 8192 ``` -------------------------------- ### Client Monitoring Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/clients.md A Go program demonstrating how to monitor connected MQTT clients, their subscriptions, and inflight messages every 10 seconds. ```go package main import ( "fmt" "log" "time" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/listeners" ) func monitorClients(server *mqtt.Server) { ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() for range ticker.C { clients := server.Clients.GetAll() fmt.Printf("Connected clients: %d\n", len(clients)) for id, client := range clients { fmt.Printf(" %s: %s (%s, proto=%d)\n", id, client.Net.Remote, string(client.Properties.Username), client.Properties.ProtocolVersion) fmt.Printf(" Subscriptions: %d\n", client.State.Subscriptions.Len()) fmt.Printf(" Inflight: %d\n", client.State.Inflight.Len()) for _, sub := range client.State.Subscriptions.GetAll() { fmt.Printf(" - %s (QoS %d)\n", sub.Filter, sub.Qos) } } fmt.Println() } } func main() { server := mqtt.New(nil) server.AddListener(listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", })) server.AddHook(new(auth.AllowHook), nil) go monitorClients(server) if err := server.Serve(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Serve Listener Method Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md Starts a specific listener identified by its ID, using the provided establisher function to handle new connections. ```go func (l *Listeners) Serve(id string, establisher EstablishFn) ``` -------------------------------- ### MQTT ACL Filter Matching Examples Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/auth-hooks.md Demonstrates how different topic filters with wildcards match specific and general MQTT topics. Use these examples to define read/write permissions for various topic patterns. ```go // Filter "#" matches all topics (except $SYS) "#": auth.ReadOnly ``` ```go // Filter "sensors/+/data" matches: // sensors/temp/data // sensors/humidity/data // But NOT: // sensors/data (only one level) // sensors/room1/floor2/data (three levels) "sensors/+/data": auth.ReadWrite ``` ```go // Multiple specific paths "users/alice/#": auth.ReadWrite "users/bob/#": auth.ReadOnly "admin/commands": auth.WriteOnly ``` -------------------------------- ### BadgerDB Backup Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/storage-hooks.md Demonstrates how to initiate a backup of the BadgerDB storage backend. The backup destination is provided by an `io.Writer` interface, and a timestamp of 0 indicates reading the latest data. ```go import "github.com/dgraph-io/badger/v3" db, err := badger.Open(badger.DefaultOptions("./data")) defer db.Close() // Create backup err = db.Backup(w, 0) // 0 = read latest ``` -------------------------------- ### OnPublish Hook Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/hooks.md Implement the OnPublish hook to modify incoming PUBLISH packets. This example restricts non-authenticated clients to QoS 0 messages. ```go func (h *MyHook) OnPublish(cl *mqtt.Client, pk packets.Packet) (packets.Packet, error) { // Only allow QoS 0 for non-authenticated clients if cl.Properties.ProtocolVersion < 5 && pk.FixedHeader.Qos > 0 { return pk, packets.ErrQosNotSupported } return pk, nil } ``` -------------------------------- ### Complete Auth Ledger Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/auth-hooks.md Demonstrates setting up a comprehensive authentication and authorization ledger. This includes defining user credentials, IP-based access rules, and granular topic access control (ACLs) for different users and network segments. ```go package main import ( "log" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { server := mqtt.New(nil) // Create auth hook with ledger ledger := &auth.Ledger{ Auth: auth.AuthRules{ // Allow specific user {Username: "admin", Password: "adminpass", Allow: true}, // Allow user from specific IP {Username: "sensor1", Password: "sensor1pass", Remote: "192.168.1.100:*", Allow: true}, // Allow anyone from localhost {Remote: "127.0.0.1:*", Allow: true}, {Remote: "localhost:*", Allow: true}, // Deny everyone else {Allow: false}, }, ACL: auth.ACLRules{ // Localhost has full access {Remote: "127.0.0.1:*", Filters: auth.Filters{ "#": auth.ReadWrite, }}, // Admin can do anything {Username: "admin", Filters: auth.Filters{ "#": auth.ReadWrite, }}, // Sensors can only publish to their own topic {Username: "sensor1", Filters: auth.Filters{ "sensors/sensor1/data": auth.WriteOnly, "sensors/sensor1/status": auth.WriteOnly, "commands/sensor1": auth.ReadOnly, }}, // Default: read-only to public topics {Filters: auth.Filters{ "public/#": auth.ReadOnly, "systems/#": auth.Deny, "#": auth.Deny, }}, }, } err := server.AddHook(new(auth.Hook), &auth.Options{Ledger: ledger}) if err != nil { log.Fatal(err) } // Add listeners tcp := listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", }) server.AddListener(tcp) // Start server if err := server.Serve(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### OnACLCheck Hook Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/hooks.md An example implementation of the `OnACLCheck` hook, used for topic-based access control. It allows publishing only to topics prefixed with the client's ID and allows all subscriptions. ```go func (h *MyHook) OnACLCheck(cl *mqtt.Client, topic string, write bool) bool { if write { return strings.HasPrefix(topic, "users/"+cl.ID+"/") } return true // allow all subscriptions } ``` -------------------------------- ### ServeAll Listeners Method Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md Starts all listeners within the container. This is typically called by the main Server.Serve() method. ```go func (l *Listeners) ServeAll(establisher EstablishFn) ``` -------------------------------- ### Example ACLRules Configuration Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/auth-hooks.md Provides an example of configuring ACLRules. Rules are evaluated in order, with the first match determining topic access. The `Filters` map specifies topic filters and their associated permissions (ReadOnly, WriteOnly, ReadWrite, Deny). A default rule can be set to grant or deny access to all other topics. ```go auth.ACLRules{ {Remote: "127.0.0.1:*", Filters: auth.Filters{ "#": auth.ReadWrite, // Localhost admin - full access }}, {Username: "alice", Filters: auth.Filters{ "users/alice/#": auth.ReadWrite, "shared/+/data": auth.ReadOnly, }}, {Username: "bob", Filters: auth.Filters{ "users/bob/#": auth.ReadWrite, "shared/+/control": auth.WriteOnly, "admin/#": auth.Deny, }}, {Filters: auth.Filters{ "#": auth.ReadOnly, // Default: read-only to all topics }}, } ``` -------------------------------- ### MQTT Server with Persistence Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/README.md This example demonstrates setting up an MQTT server with persistent storage using BadgerDB. This ensures messages and client states are saved across restarts. ```go package main import ( "log" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/hooks/storage/badger" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { server := mqtt.New(nil) // Add persistent storage server.AddHook(new(badger.Hook), &badger.Options{ Path: "./data", }) // Add TCP listener server.AddListener(listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", })) // Add auth server.AddHook(new(auth.AllowHook), nil) if err := server.Serve(); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Listeners.Serve Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md Starts a specific listener identified by its ID, using the provided establisher function to handle new connections. ```APIDOC ## Listeners.Serve ### Description Start a specific listener. ### Method Listeners.Serve ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **id** (string) - Required - The unique identifier of the listener to start. * **establisher** (EstablishFn) - Required - The callback function to handle new connections. ``` -------------------------------- ### YAML Configuration File Structure Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Example structure for an MQTT server configuration file in YAML format, detailing listeners, hooks, options, and capabilities. ```yaml listeners: - type: "tcp" id: "tcp1" address: ":1883" - type: "ws" id: "ws1" address: ":1882" hooks: auth: allow_all: true options: inline_client: true sys_topic_resend_interval: 10 capabilities: maximum_clients: 10000 maximum_qos: 2 ``` -------------------------------- ### Example of Invalid Configuration Type Usage Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/errors.md Demonstrates how ErrInvalidConfigType can be triggered. This example shows passing a string where a pointer to auth.Options is expected, leading to the error. ```go // Auth hook expects *auth.Options err := server.AddHook(new(auth.Hook), "invalid") // string instead of *Options // Returns: ErrInvalidConfigType ``` -------------------------------- ### Configure Server Logging Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Set up server logging using the `slog` package. This example configures the log level to Debug and outputs logs to standard output in text format. ```go import "log/slog" // Set log level level := new(slog.LevelVar) level.Set(slog.LevelDebug) server.Log = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ Level: level, })) ``` -------------------------------- ### File-Based Configuration Example Source: https://github.com/mochi-mqtt/server/blob/main/README.md A sample YAML configuration file for the Mochi MQTT server. It defines TCP and WebSocket listeners, a system info listener, and enables the 'allow-all' authentication hook. ```yaml listeners: - type: "tcp" id: "tcp12" address: ":1883" - type: "ws" id: "ws1" address: ":1882" - type: "sysinfo" id: "stats" address: ":1880" hooks: auth: allow_all: true options: inline_client: true ``` -------------------------------- ### MQTT Server with Inline Publishing and Subscribing Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/README.md This example shows how to enable inline client functionality in the MQTT server, allowing you to publish and subscribe to topics directly from your Go application code. ```go package main import ( "log" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { // Create server with inline client enabled server := mqtt.New(&mqtt.Options{ InlineClient: true, }) server.AddListener(listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", })) server.AddHook(new(auth.AllowHook), nil) go server.Serve() // Publish from embedding code err := server.Publish("sensors/temperature", []byte("23.5"), false, 0) if err != nil { log.Fatal(err) } // Subscribe from embedding code handler := func(cl *mqtt.Client, sub mqtt.packets.Subscription, pk mqtt.packets.Packet) { log.Printf("Received: %s = %s", pk.TopicName, string(pk.Payload)) } err = server.Subscribe("sensors/+/data", 1, handler) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### DisconnectClient Example Usage Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/server.md Demonstrates how to disconnect a client using the DisconnectClient method with a specific reason code. ```go err := server.DisconnectClient(client, packets.ErrSessionTakenOver) ``` -------------------------------- ### Custom Hook Implementation Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/hooks.md Demonstrates how to create a custom hook by embedding `HookBase` and overriding specific methods like `ID`, `Provides`, `Init`, and an event handler `OnPublish`. ```go type MyHook struct { mqtt.HookBase config *MyConfig } func (h *MyHook) ID() string { return "my-hook" } func (h *MyHook) Provides(b byte) bool { return b == mqtt.OnPublish } func (h *MyHook) Init(config any) error { /* ... */ } func (h *MyHook) OnPublish(cl *mqtt.Client, pk packets.Packet) (packets.Packet, error) { // Custom logic here return pk, nil } ``` -------------------------------- ### Add PebbleDB Storage Hook Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Integrate PebbleDB as a storage solution. This example shows how to set the path and mode for PebbleDB. ```go import "github.com/mochi-mqtt/server/v2/hooks/storage/pebble" server.AddHook(new(pebble.Hook), &pebble.Options{ Path: "./data", Mode: pebble.Sync, }) ``` -------------------------------- ### Server Methods Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/server.md Core methods for managing the MQTT server lifecycle, including starting the server, adding listeners, and integrating hooks. ```APIDOC ## Serve ### Description Starts the event loops responsible for establishing client connections on all attached listeners, publishing system topics, and starting all hooks. ### Signature ```go func (s *Server) Serve() error ``` ### Parameters None ### Returns `error` - An error if the server fails to start, nil on success. ### Errors - Listener initialization errors - Hook initialization errors - Storage persistence errors ### Example ```go server := mqtt.New(nil) // Add listeners and hooks... err := server.Serve() if err != nil { log.Fatal(err) } // Server is now running and accepting connections ``` ``` ```APIDOC ## AddListener ### Description Adds a new network listener to the server for receiving incoming client connections. ### Signature ```go func (s *Server) AddListener(l listeners.Listener) error ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Description | |-----------|------|-------------| | l | `listeners.Listener` | The listener to attach to the server. Must have a unique ID. | ### Returns `error` - An error if the listener ID already exists or initialization fails. ### Errors - `ErrListenerIDExists` - A listener with the same ID is already attached - Listener initialization errors ### Example ```go server := mqtt.New(nil) // Add a TCP listener tcp := listeners.NewTCP(listeners.Config{ ID: "tcp1", Address: ":1883", }) if err := server.AddListener(tcp); err != nil { log.Fatal(err) } // Add a WebSocket listener ws := listeners.NewWebsocket(listeners.Config{ ID: "ws1", Address: ":1882", }) if err := server.AddListener(ws); err != nil { log.Fatal(err) } ``` ``` ```APIDOC ## AddListenersFromConfig ### Description Adds multiple listeners specified in configuration, typically loaded from a configuration file. ### Signature ```go func (s *Server) AddListenersFromConfig(configs []listeners.Config) error ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Description | |-----------|------|-------------| | configs | `[]listeners.Config` | Array of listener configurations. | ### Returns `error` - An error if any listener configuration is invalid or fails to initialize. ### Supported Types - "tcp" - TCP listener - "ws" - WebSocket listener - "unix" - Unix socket listener - "healthcheck" - HTTP health check endpoint - "sysinfo" - HTTP system info dashboard - "mock" - Mock listener for testing ### Example ```go configs := []listeners.Config{ {Type: "tcp", ID: "tcp1", Address: ":1883"}, {Type: "ws", ID: "ws1", Address: ":1882"}, } err := server.AddListenersFromConfig(configs) ``` ``` ```APIDOC ## AddHook ### Description Attaches a new hook to the server for event handling. Should be called before `Serve()` is invoked. ### Signature ```go func (s *Server) AddHook(hook Hook, config any) error ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Description | |-----------|------|-------------| | hook | `Hook` | The hook implementation to attach. | | config | `any` | Hook-specific configuration, or nil for default. | ### Returns `error` - An error if hook initialization fails. ### Example ```go import "github.com/mochi-mqtt/server/v2/hooks/auth" server := mqtt.New(nil) // Add allow-all auth hook (development only) err := server.AddHook(new(auth.AllowHook), nil) if err != nil { log.Fatal(err) } // Add auth ledger err = server.AddHook(new(auth.Hook), &auth.Options{ Ledger: &auth.Ledger{ Auth: auth.AuthRules{ {Username: "user1", Password: "pass1", Allow: true}, }, }, }) ``` ``` ```APIDOC ## AddHooksFromConfig ### Description Adds multiple hooks specified in configuration. ### Signature ```go func (s *Server) AddHooksFromConfig(hooks []HookLoadConfig) error ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Description | |-----------|------|-------------| | hooks | `[]HookLoadConfig` | Array of hook configurations. | ### Returns `error` - An error if any hook fails to initialize. ### Example ```go hookConfigs := []mqtt.HookLoadConfig{ // Loaded from configuration file } err := server.AddHooksFromConfig(hookConfigs) ``` ``` -------------------------------- ### Listeners.ServeAll Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md Starts all listeners managed by the container. This method is typically called by the main server to initiate all listening services. ```APIDOC ## Listeners.ServeAll ### Description Start all listeners. ### Method Listeners.ServeAll ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * **establisher** (EstablishFn) - Required - The callback function to handle new connections for all listeners. ``` -------------------------------- ### Get Client Information Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Retrieves and logs basic information, subscriptions, and in-flight messages for a specific client. ```go if client, ok := server.Clients.Get("myclient"); ok { // Basic info log.Printf("ID: %s", client.ID) log.Printf("Remote: %s", client.Net.Remote) log.Printf("Listener: %s", client.Net.Listener) log.Printf("Username: %s", string(client.Properties.Username)) log.Printf("Protocol: MQTT v%d", client.Properties.ProtocolVersion) // Subscriptions for _, sub := range client.State.Subscriptions.GetAll() { log.Printf("Subscribed: %s (QoS %d)", sub.Filter, sub.Qos) } // In-flight messages log.Printf("Inflight: %d", client.State.Inflight.Len()) for _, pk := range client.State.Inflight.GetAll() { log.Printf("In-flight: %s (ID %d)", pk.TopicName, pk.PacketID) } } ``` -------------------------------- ### Build and Run Mochi MQTT Docker with Configuration Source: https://github.com/mochi-mqtt/server/blob/main/README.md Build a custom Mochi MQTT Docker image and run it, exposing ports and mounting a configuration file. This setup includes Websocket, TCP, and Stats server listeners. ```sh docker build -t mochi:latest . ``` ```sh docker run -p 1883:1883 -p 1882:1882 -p 8080:8080 -v $(pwd)/config.yaml:/config.yaml mochi:latest ``` -------------------------------- ### Configure BadgerDB Storage Hook from YAML Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/storage-hooks.md Example of configuring the BadgerDB storage hook using a YAML configuration file, specifying the database path. ```yaml hooks: storage: badger: path: ./data/mqtt ``` -------------------------------- ### Server Core API Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/INDEX.md Reference for the main MQTT Server type, including methods for creation, starting, configuration, and inline client operations. ```APIDOC ## Server Core API ### Description Provides access to the main MQTT Server type and its associated methods for managing the broker's lifecycle and operations. ### Methods - `New()`: Create a new server instance. - `Serve()`: Start the MQTT broker. - `AddListener(listener Listener)`: Add a network listener to the server. - `AddHook(hook Hook)`: Register a hook for event handling. - `Publish(clientid string, topic string, size int64, qos byte, retain bool, payload io.Reader) error`: Publish a message inline. - `Subscribe(clientid string, qos byte, topic string) error`: Subscribe a client to a topic inline. - `Unsubscribe(clientid string, topic string) error`: Unsubscribe a client from a topic inline. - `DisconnectClient(clientid string, force bool) error`: Disconnect a client. - `InjectPacket(clientid string, packet mqtt.Packet) error`: Inject a packet to a client. - `NewClient(clientid string) Client`: Create a new client instance. ### Properties - `Options`: Server configuration options. - `Clients`: Access to the client container. - `Listeners`: Access to the listeners container. - `Topics`: Access to the topic tree. - `Info`: Server information. - `Log`: Server logger. ``` -------------------------------- ### OnStarted Hook Event Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/hooks.md Callback executed after the Mochi MQTT server has successfully started and all listeners are active. Useful for initializing external resources or logging startup information. ```APIDOC ### OnStarted ```go OnStarted() ``` Called when the server has successfully started and all listeners are active. **Use case:** Initialize external resources, log startup info. ``` -------------------------------- ### Storage Hook Error Example (BadgerDB) Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/errors.md Demonstrates a potential error when initializing a storage hook, such as the BadgerDB hook, with an invalid path. This can result in errors like 'permission denied' or 'no such file or directory'. ```go import "github.com/mochi-mqtt/server/v2/hooks/storage/badger" err := server.AddHook(new(badger.Hook), &badger.Options{ Path: "/nonexistent/directory/db", }) // May return: permission denied, no such file or directory ``` -------------------------------- ### Accessing Client Connection Info Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/clients.md Shows how to get a client's connection details and print its remote address, listener ID, and inline status. ```go client, _ := server.Clients.Get("myclient") fmt.Printf("Remote: %s\n", client.Net.Remote) fmt.Printf("Listener: %s\n", client.Net.Listener) fmt.Printf("Inline: %v\n", client.Net.Inline) ``` -------------------------------- ### ACL Rule Priority Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/auth-hooks.md Illustrates how ACL rules are prioritized, with the first matching rule taking precedence. Place more specific rules before less specific ones. ```go auth.ACLRules{ // Most specific rules first {Username: "alice", Filters: auth.Filters{ "secrets/#": auth.Deny, // Explicitly deny Alice }}, // Less specific rules later {Username: "alice", Filters: auth.Filters{ "#": auth.ReadWrite, // Alice can read/write most topics }}, // Catch-all last {Filters: auth.Filters{ "#": auth.ReadOnly, // Default: read-only }}, } ``` -------------------------------- ### Initialize Redis Storage Hook with Clustering Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/storage-hooks.md Initializes the Redis storage hook for a Redis cluster setup. Provide a list of cluster node addresses and any necessary authentication. ```go import redis "github.com/go-redis/redis/v8" err := server.AddHook(new(redis.Hook), &redis.Options{ Options: &redis.ClusterOptions{ Addrs: []string{ "redis1:6379", "redis2:6379", "redis3:6379", }, Password: "clusterpass", }, }) ``` -------------------------------- ### Example of ErrInlineClientNotEnabled Usage Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/errors.md Shows the incorrect usage leading to ErrInlineClientNotEnabled and the correct way to enable the inline client for server operations. Ensure inline client is enabled in server options. ```go // Without inline client enabled server.Publish("topic", []byte("data"), false, 0) // Returns: ErrInlineClientNotEnabled // Correct usage server := mqtt.New(&mqtt.Options{InlineClient: true}) server.Publish("topic", []byte("data"), false, 0) // OK ``` -------------------------------- ### Get Clients by Listener Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/clients.md Fetches all clients connected through a specific listener, identified by the listener's ID. Returns an empty slice if no clients are found for the listener. ```go tcpClients := server.Clients.GetByListener("tcp1") fmt.Printf("Clients on tcp1: %d\n", len(tcpClients)) ``` -------------------------------- ### HTTP Stats Listener Example Response Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md An example JSON response from the HTTP Stats listener, showing server metrics. ```json { "version": "2.7.9", "started": 1719660000, "clients_connected": 42, "clients_maximum": 150, "subscriptions": 89, "subscriptions_maximum": 500, "retained_messages": 23, "inflight": 5 } ``` -------------------------------- ### HTTP Health Check Listener Example Response Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md An example response from the HTTP Health Check listener, indicating the server is running. ```text HTTP/1.1 200 OK Content-Type: text/plain OK ``` -------------------------------- ### Load Server Configuration from File Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Loads MQTT server options from a YAML configuration file and initializes a new server instance. ```go // Load config opts := &mqtt.Options{} err := mqtt.LoadConfig("config.yaml", opts) if err != nil { log.Fatal(err) } server := mqtt.New(opts) ``` -------------------------------- ### OnConnectAuthenticate Hook Example Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/hooks.md An example implementation of the `OnConnectAuthenticate` hook, which validates client credentials. Return true to allow the connection, false to deny. ```go func (h *MyHook) OnConnectAuthenticate(cl *mqtt.Client, pk packets.Packet) bool { username := string(pk.Connect.Username) password := string(pk.Connect.Password) return h.validateCredentials(username, password) } ``` -------------------------------- ### Configure Server Capabilities Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Initializes a new MQTT server with specific capabilities defined in mqtt.Options. ```go server := mqtt.New(&mqtt.Options{ Capabilities: &mqtt.Capabilities{ MaximumClients: 10000, MaximumQos: 2, ReceiveMaximum: 1024, MaximumInflight: 8192, RetainAvailable: 1, WildcardSubAvailable: 1, }, }) ``` -------------------------------- ### Import and Initialize Mochi MQTT Server Source: https://github.com/mochi-mqtt/server/blob/main/README.md This snippet shows how to import the Mochi MQTT server package and initialize a basic server instance with a TCP listener and an allow-all authentication hook. It includes signal handling for graceful shutdown. ```go import ( "log" "os" "os/signal" "syscall" mqtt "github.com/mochi-mqtt/server/v2" "github.com/mochi-mqtt/server/v2/hooks/auth" "github.com/mochi-mqtt/server/v2/listeners" ) func main() { // Create signals channel to run server until interrupted sigs := make(chan os.Signal, 1) done := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigs done <- true }() // Create the new MQTT Server. server := mqtt.New(nil) // Allow all connections. _ = server.AddHook(new(auth.AllowHook), nil) // Create a TCP listener on a standard port. tcp := listeners.NewTCP(listeners.Config{ID: "t1", Address": ":1883"}) err := server.AddListener(tcp) if err != nil { log.Fatal(err) } go func() { err := server.Serve() if err != nil { log.Fatal(err) } }() // Run server until interrupted <-done // Cleanup } ``` -------------------------------- ### Get Inflight Message Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/clients.md Retrieves an inflight message by its ID. ```go func (i *Inflight) Get(id uint16) (*packets.Packet, bool) ``` -------------------------------- ### New Server Constructor Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/server.md Creates and returns a new MQTT server instance with optional configuration. If nil options are provided, default options are applied. ```APIDOC ## New ### Description Creates and returns a new MQTT server instance with optional configuration. ### Signature ```go func New(opts *Options) *Server ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters Table | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | opts | `*Options` | nil | Server configuration options. If nil, default options are applied. | ### Returns `*Server` - A fully initialized broker server instance. ### Example ```go package main import ( "log" mqtt "github.com/mochi-mqtt/server/v2" ) func main() { // Create a new server with default options server := mqtt.New(nil) // Or with custom options server := mqtt.New(&mqtt.Options{ InlineClient: true, SysTopicResendInterval: 10, }) } ``` ``` -------------------------------- ### TopicAliases Get Method Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/clients.md Retrieves the topic name associated with a given alias. ```go func (ta *TopicAliases) Get(alias uint16) (string, bool) ``` -------------------------------- ### Create New MQTT Server Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/server.md Creates a new MQTT server instance. Use nil for default options or provide a pointer to mqtt.Options for custom configuration. ```go package main import ( "log" mqtt "github.com/mochi-mqtt/server/v2" ) func main() { // Create a new server with default options server := mqtt.New(nil) // Or with custom options server := mqtt.New(&mqtt.Options{ InlineClient: true, SysTopicResendInterval: 10, }) } ``` -------------------------------- ### Check Redis Memory Usage Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/storage-hooks.md Use the `redis-cli` command to get memory usage information for Redis. ```bash redis-cli info memory ``` -------------------------------- ### Configure Mochi MQTT Server Options Source: https://github.com/mochi-mqtt/server/blob/main/README.md This snippet demonstrates how to initialize a Mochi MQTT server with custom options, including capabilities like maximum session expiry, client writes pending, and compatibility settings. Adjust buffer sizes and resend intervals based on your specific needs and expected client load. ```go server := mqtt.New(&mqtt.Options{ Capabilities: mqtt.Capabilities{ MaximumSessionExpiryInterval: 3600, MaximumClientWritesPending: 3, Compatibilities: mqtt.Compatibilities{ ObscureNotAuthorized: true, }, }, ClientNetWriteBufferSize: 4096, ClientNetReadBufferSize: 4096, SysTopicResendInterval: 10, InlineClient: false, }) ``` -------------------------------- ### OnSessionEstablish Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/hooks.md Called immediately after client authenticates and before CONNACK is sent. Used for final setup and loading client-specific data. ```APIDOC ## OnSessionEstablish ### Description Called immediately after client authenticates and before CONNACK is sent. Perform final setup, load client-specific data. ### Parameters #### Path Parameters - **cl** (*Client) - Required - The authenticated client. - **pk** (packets.Packet) - Required - The CONNECT packet. ### Use case: Perform final setup, load client-specific data. ``` -------------------------------- ### Create New Client Instance Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/server.md Creates a new client instance for direct interaction with the server. Set 'inline' to true to bypass ACL and topic validation checks. ```go // Create an inline client for direct publishing inlineClient := server.NewClient(nil, "local", "publisher", true) // Create a client from a network connection netClient := server.NewClient(conn, "tcp1", "client123", false) ``` -------------------------------- ### Get Subscription Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/clients.md Retrieves a subscription based on its topic filter string. Returns the subscription and a boolean indicating if it was found. ```go func (s *Subscriptions) Get(filter string) (packets.Subscription, bool) ``` -------------------------------- ### Create Mock Listener Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md Use this for testing purposes as it does not establish actual network connections. Provide an ID and an optional address. ```go mock := listeners.NewMockListener("mock1", "") server.AddListener(mock) ``` -------------------------------- ### Chain Multiple Authentication Hooks Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/auth-hooks.md Demonstrates how to chain multiple authentication hooks to the server. All hooks must pass for authentication to succeed. ```go // First hook: check username/password server.AddHook(new(auth.Hook), &auth.Options{Ledger: ledger}) // Second hook: check IP whitelist server.AddHook(new(IPWhitelistHook), nil) // Third hook: check rate limits server.AddHook(new(RateLimitHook), nil) ``` -------------------------------- ### Server Max QoS Configuration Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/errors.md Demonstrates how to configure the server's maximum supported QoS level. Connecting with a higher requested QoS will result in an ErrQosNotSupported error. ```go server.Options.Capabilities.MaximumQos = 1 // Client attempting QoS 2 will receive ErrQosNotSupported ``` -------------------------------- ### Example of ErrListenerIDExists Usage Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/errors.md Demonstrates the scenario where adding a listener with a duplicate ID results in ErrListenerIDExists. Use unique IDs for each listener. ```go server.AddListener(tcp1) // OK server.AddListener(tcp2) // Same ID as tcp1 - returns ErrListenerIDExists ``` -------------------------------- ### Create Mochi MQTT Server Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Instantiate a new Mochi MQTT server. Use default options or provide a custom mqtt.Options struct for specific configurations. ```go // Basic server server := mqtt.New(nil) ``` ```go // With options server := mqtt.New(&mqtt.Options{ InlineClient: true, SysTopicResendInterval: 10, ClientNetWriteBufferSize: 4096, }) ``` -------------------------------- ### Get Connected Client Count Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/QUICK-REFERENCE.md Obtain the total number of currently connected clients. This provides a quick overview of server load. ```go // Get client count count := server.Clients.Len() ``` -------------------------------- ### Build and Run Mochi MQTT Broker with Go Source: https://github.com/mochi-mqtt/server/blob/main/README.md Compile and run the Mochi MQTT broker locally using Go. This command builds the executable and then runs it. ```bash cd cmd go build -o mqtt && ./mqtt ``` -------------------------------- ### Get Listener Method Source: https://github.com/mochi-mqtt/server/blob/main/_autodocs/api-reference/listeners.md Retrieves a specific listener from the container using its unique ID. Returns the listener and a boolean indicating if it was found. ```go func (l *Listeners) Get(id string) (Listener, bool) ```