bmux

package module
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2025 License: MIT Imports: 13 Imported by: 0

README

bmux

bmux is a modular TCP multiplexer and routing framework for Go. It provides a declarative interface for handling custom binary protocols using a router and middleware architecture inspired by modern web frameworks.

Features

  • Global, router-level, and route-level middleware chaining
  • Organize handlers into routers with isolated configuration
  • Parse and dispatch TCP messages using generic packet structures
  • Built on top of the gnet async networking engine for efficient concurrency
  • Load runtime options via config.Config

Installation

go get github.com/etwodev/bmux

Basic Usage

import (
	"github.com/etwodev/bmux"
	"github.com/etwodev/bmux/router"
)

// Define your context struct
type MyContext struct {
	Command int32
}

// Define extraction functions as needed for your protocol

func main() {
	// Provide context factory and extraction functions to bmux.New
	contextFactory := func() *MyContext { return &MyContext{} }
	extractLength := func(c gnet.Conn, buf []byte) (headLen, totalLen int) { /* ... */ }
	extractMsgID := func(c gnet.Conn, head []byte) int { /* ... */ }

	server := bmux.New(contextFactory, extractLength, extractMsgID, nil)

	// Create router and register routes
	r := router.New("main")
	r.Route(1, router.HandlerFunc(func(ctx *router.Context) {
		// handle message with ID 1
	}))
	server.LoadRouter([]router.Router{r})

	// Start the server (listens on config.Address() and config.Port())
	server.Start()
}

Middleware

Middleware can be applied at three levels:

  • Global — applies to all routes
  • Router-Level — applies to all routes within a router
  • Route-Level — applies to individual routes
Example: Logging Middleware
logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
loggingMiddleware := middleware.NewLoggingMiddleware(logger)
server.LoadMiddleware([]middleware.Middleware{loggingMiddleware})

Inside a handler:

if l := ctx.Context.Value(middleware.LoggerCtxKey); l != nil {
    if logger, ok := l.(zerolog.Logger); ok {
        logger.Info().Msg("Processing route")
    }
}

Configuration

bmux uses the config.Config struct to load runtime settings such as:

  • Server address and port
  • Logging level (e.g., debug, info, warn)
  • Timeout durations (read, write, idle, shutdown)
  • Maximum concurrent connections
  • Enable or disable multi-core mode for gnet

Call config.New() early in your application to initialize the configuration.

Project Structure

bmux/
├── bmux.go          → Core server and lifecycle management
├── pkg/config/          → Configuration loading and management
├── pkg/middleware/      → Middleware primitives and implementations
├── pkg/router/          → Router, route, and context definitions
├── pkg/engine/          → Core networking engine integration (gnet wrapper)

Example Config File

{
	"port": 9000,
	"address": "0.0.0.0",
	"experimental": false,
	"logLevel": "info",
	"maxConnections": 100,
	"readTimeout": 2,
	"shutdownTimeout": 15,
	"enableMulticore": true
}

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests when applicable
  4. Submit a pull request with a clear description

License

MIT License © 2025 etwodev

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option[T any] func(*Server[T])

Option defines a functional option to customize the Server.

type Server

type Server[T any] struct {
	// contains filtered or unexported fields
}

Server represents the bmux TCP server instance. It manages routers, middleware, and the underlying event engine.

T is a generic type parameter representing the connection context type.

Usage:

ctxFactory := func() *MyContext { return &MyContext{} }
extractLen := func(c gnet.Conn, buf []byte) (headLen, totalLen int) { ... }
extractID := func(c gnet.Conn, head []byte) int { ... }

server := bmux.New(ctxFactory, extractLen, extractID, nil)
server.LoadRouter(myRouters)
server.LoadMiddleware(myMiddleware)
server.Start()

The server handles connections using gnet for high-performance async I/O.

func New

func New[T any](
	contextFactory func() *T,
	extractLength engine.ExtractLengthFunc[T],
	extractMsgID engine.ExtractMsgIDFunc[T],
	override *config.Config,
	opts ...Option[T],
) *Server[T]

New creates a new bmux Server instance with the given context factory, length extractor, message ID extractor, optional config override, and options.

It validates required arguments and loads configuration.

Example:

ctxFactory := func() *MyContext { return &MyContext{} }
extractLen := func(c gnet.Conn, buf []byte) (headLen, totalLen int) { ... }
extractID := func(c gnet.Conn, head []byte) int { ... }

server := bmux.New(ctxFactory, extractLen, extractID, nil)

The server is ready to have routers and middleware loaded before starting.

func (*Server[T]) LoadMiddleware

func (s *Server[T]) LoadMiddleware(middleware []middleware.Middleware)

LoadMiddleware appends global middleware to the server.

Middleware applied here runs for all routes.

Example:

server.LoadMiddleware([]middleware.Middleware{myMiddleware})

func (*Server[T]) LoadRouter

func (s *Server[T]) LoadRouter(routes []router.Router)

LoadRouter appends one or more routers to the server.

Routers contain groups of routes and their associated middleware.

Example:

myRouter := router.NewRouter(true, routes, middleware, opts...)
server.LoadRouter([]router.Router{myRouter})

func (*Server[T]) Shutdown

func (s *Server[T]) Shutdown(ctx context.Context) error

Shutdown gracefully stops the server using the provided context for timeout control.

Returns any error encountered during shutdown.

Example:

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
err := server.Shutdown(ctx)

func (*Server[T]) Start

func (s *Server[T]) Start()

Start launches the server, listening on the configured address and port, and gracefully handles shutdown on system interrupts.

It blocks until the server exits.

Example:

server.Start()

Directories

Path Synopsis
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL