fibergun

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 22, 2024 License: MIT Imports: 7 Imported by: 0

README

Fiber GunDB Middleware

Go Reference Go Report Card

GunDB middleware for Fiber web framework. This middleware enables easy integration of GunDB, a decentralized database, with your Fiber applications.

Install

This middleware supports Fiber v2.

go get -u github.com/gofiber/fiber/v2
go get -u github.com/streamerd/fibergun

Signature

fibergun.New(config ...*fibergun.Config) fiber.Handler

Config

Property Type Description Default
Next func(*fiber.Ctx) bool A function to skip this middleware when returned true nil
WebSocketEndpoint string The endpoint where GunDB websocket connections will be handled "/gun"
StaticPath string The path to serve the GunDB client files "./public"
HeartbeatInterval time.Duration Interval for sending heartbeat pings 15 * time.Second
PeerTimeout time.Duration Duration after which a peer is considered inactive 60 * time.Second
MaxMessageSize int64 Maximum size of a WebSocket message in bytes 1024 * 1024 (1MB)
EnableCompression bool Enables WebSocket compression true
BufferSize int Sets the read/write buffer size for WebSocket connections 1024 * 16 (16KB)
Debug bool Enables detailed logging false
ReconnectAttempts int Number of times to attempt reconnection 5
ReconnectInterval time.Duration Time to wait between reconnection attempts 2 * time.Second
DataReplication DataReplicationConfig Configures how data is replicated between peers See below
DataReplicationConfig
Property Type Description Default
Enabled bool Determines if data should be replicated between peers true
SyncInterval time.Duration How often to sync data between peers 30 * time.Second
MaxRetries int Maximum number of sync retries 3
BatchSize int Maximum number of items to sync at once 100

Example

Server Setup
package main

import (
    "log"
    "time"
    
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/cors"
    "github.com/gofiber/fiber/v2/middleware/logger"
    "github.com/streamerd/fibergun"
)

func main() {
    app := fiber.New(fiber.Config{
        DisableStartupMessage: false,
    })

    // Add middleware
    app.Use(logger.New(logger.Config{
        Format:     "${time} ${status} - ${latency} ${method} ${path}\n",
        TimeFormat: "15:04:05",
        TimeZone:   "Local",
    }))

    app.Use(cors.New(cors.Config{
        AllowOrigins: "*",
        AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH,OPTIONS",
        AllowHeaders: "*",
    }))

    // Initialize GunDB middleware
    app.Use(fibergun.New(&fibergun.Config{
        StaticPath:        "./public",
        WebSocketEndpoint: "/gun",
        HeartbeatInterval: 15 * time.Second,
        PeerTimeout:       60 * time.Second,
        EnableCompression: true,
        BufferSize:        1024 * 16,
        Debug:            true,
        DataReplication: fibergun.DataReplicationConfig{
            Enabled:      true,
            SyncInterval: 5 * time.Second,
            MaxRetries:   5,
            BatchSize:    100,
        },
    }))

    app.Static("/", "./public")

    log.Printf("Starting server on :3000...")
    log.Fatal(app.Listen(":3000"))
}
Client Example

Create public/index.html:

<!DOCTYPE html>
<html>
<head>
    <title>GunDB + Fiber Example</title>
    <script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
</head>
<body>
    <div class="container">
        <h1>GunDB + Fiber Example</h1>
        <div id="status"></div>

        <div class="message-form">
            <input type="text" id="nameInput" placeholder="Your name" />
            <textarea id="messageInput" placeholder="Type your message"></textarea>
            <button onclick="sendMessage()">Send Message</button>
        </div>

        <div id="messages"></div>
    </div>

    <script>
        const gun = GUN({
            peers: [`ws://${window.location.host}/gun`],
            localStorage: true,
            debug: true,
            axe: false,
            retry: 1000
        });

        const messages = gun.get('chat');

        function sendMessage() {
            const name = nameInput.value.trim() || 'Anonymous';
            const text = messageInput.value.trim();
            
            if (!text) return;

            const messageId = Date.now().toString();
            messages.get(messageId).put({
                name: name,
                text: text,
                timestamp: Date.now(),
                id: messageId
            });

            messageInput.value = '';
        }

        messages.map().on((data, key) => {
            if (!data || !data.timestamp) return;
            displayMessage(data);
        });
    </script>
</body>
</html>

Features

  1. Real-time peer-to-peer communication
  2. Message persistence across peers
  3. Automatic peer discovery and sync
  4. WebSocket compression support
  5. Configurable heartbeat and timeouts
  6. Data replication with retry mechanisms
  7. Debug mode for development
  8. CORS support
  9. Connection state management
  10. Automatic reconnection handling

WebSocket Handler

The middleware provides a WebSocket handler that:

  1. Manages peer connections and lifecycle
  2. Routes messages between peers
  3. Handles connection/disconnection events
  4. Facilitates data synchronization
  5. Maintains heartbeat for connection health
  6. Handles message retries and acknowledgments

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -am 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License.

Acknowledgments

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(config ...*Config) fiber.Handler

New creates a new GunDB middleware instance

Types

type Config

type Config struct {
	// Next defines a function to skip this middleware when returned true
	Next func(c *fiber.Ctx) bool

	// WebSocketEndpoint is the endpoint where GunDB websocket connections will be handled
	WebSocketEndpoint string

	// StaticPath is the path to serve the GunDB client files
	StaticPath string

	// HeartbeatInterval is the interval for sending heartbeat pings
	HeartbeatInterval time.Duration

	// PeerTimeout is the duration after which a peer is considered inactive
	PeerTimeout time.Duration

	// MaxMessageSize is the maximum size of a WebSocket message in bytes
	MaxMessageSize int64

	// EnableCompression enables WebSocket compression
	EnableCompression bool

	// BufferSize sets the read/write buffer size for WebSocket connections
	BufferSize int

	// Debug enables detailed logging
	Debug bool

	// ReconnectAttempts is the number of times to attempt reconnection
	ReconnectAttempts int

	// ReconnectInterval is the time to wait between reconnection attempts
	ReconnectInterval time.Duration

	// DataReplication configures how data is replicated between peers
	DataReplication DataReplicationConfig

	SharedStore *sync.Map
	// contains filtered or unexported fields
}

Config defines the config for GunDB middleware

func ConfigDefault

func ConfigDefault() *Config

func NewConfig

func NewConfig() *Config

NewConfig creates a new config with default values

func (*Config) Validate

func (c *Config) Validate() *Config

Validate checks and corrects the configuration values

func (*Config) WithBufferSize

func (c *Config) WithBufferSize(size int) *Config

WithBufferSize sets the WebSocket buffer size

func (*Config) WithCompression

func (c *Config) WithCompression(enabled bool) *Config

WithCompression enables or disables WebSocket compression

func (*Config) WithDataReplication

func (c *Config) WithDataReplication(config DataReplicationConfig) *Config

WithDataReplication configures data replication

func (*Config) WithDebug

func (c *Config) WithDebug(enabled bool) *Config

WithDebug enables or disables debug logging

func (*Config) WithHeartbeat

func (c *Config) WithHeartbeat(interval time.Duration) *Config

WithHeartbeat sets the heartbeat interval

func (*Config) WithTimeout

func (c *Config) WithTimeout(timeout time.Duration) *Config

WithTimeout sets the peer timeout

type DataReplicationConfig

type DataReplicationConfig struct {
	// Enabled determines if data should be replicated between peers
	Enabled bool

	// SyncInterval is how often to sync data between peers
	SyncInterval time.Duration

	// MaxRetries is the maximum number of sync retries
	MaxRetries int

	// BatchSize is the maximum number of items to sync at once
	BatchSize int
}

DataReplicationConfig defines how data is replicated between peers

type GunDB

type GunDB struct {
	// contains filtered or unexported fields
}

GunDB represents the main handler structure

func (*GunDB) Get

func (g *GunDB) Get(key string) (interface{}, error)

Update Get to check globalStore first

func (*GunDB) Put

func (g *GunDB) Put(key string, value interface{}) error

type GunGet

type GunGet struct {
	Hash string `json:"#,omitempty"`
	Key  string `json:".,omitempty"`
	Soul string `json:"#,omitempty"`
}

GunGet represents a GET request in GunDB

type GunMessage

type GunMessage struct {
	Get  *GunGet `json:"get,omitempty"`
	Put  *GunPut `json:"put,omitempty"`
	Hash string  `json:"#,omitempty"`
	Ok   *GunOk  `json:"ok,omitempty"`
	Err  string  `json:"err,omitempty"`
}

GunMessage represents various GunDB message types

type GunOk

type GunOk struct {
	Hash string                 `json:"@,omitempty"`
	Data map[string]interface{} `json:"/,omitempty"`
}

GunOk represents an acknowledgment in GunDB

type GunPut

type GunPut struct {
	Chat        map[string]interface{} `json:"chat,omitempty"`
	ChatMessage map[string]interface{} `json:"chat/message,omitempty"`
	Messages    map[string]interface{} `json:"messages,omitempty"`
	Ok          map[string]interface{} `json:"ok,omitempty"`
}

type PeerConnection

type PeerConnection struct {
	ID       string
	Conn     *websocket.Conn
	LastSeen time.Time
	Store    *sync.Map
	Active   bool
}

PeerConnection represents a connected peer

Jump to

Keyboard shortcuts

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