Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

findstr/silly

Open more actions menu

Repository files navigation

Silly

A Lightweight, High-Performance Server Framework for Lua

License CI Documentation

English | 简体中文

FeaturesQuick StartExamplesDocumentationContributing


✨ Features

  • 🚀 High Performance - Handles 200,000+ requests/second with single-threaded architecture
  • 🧵 Coroutine-Based - Clean async/await style code without callback hell
  • 🌐 Rich Protocols - Built-in support for TCP, UDP, HTTP, WebSocket, gRPC, TLS
  • 💾 Database Ready - Native MySQL, Redis, and Etcd integrations
  • 🔐 Security - Comprehensive crypto suite including JWT, AES, RSA, HMAC
  • 📊 Observability - Prometheus metrics and structured logging out of the box
  • 🔧 Developer Friendly - Hot reload, interactive debugger, and extensive APIs

🚀 Quick Start

Installation

# Clone the repository
git clone https://github.com/findstr/silly.git
cd silly

# Build (supports Linux, macOS, Windows)
# OpenSSL support is enabled by default for TLS
make

# Disable OpenSSL if not needed
make OPENSSL=off

Hello World

Create a file hello.lua:

local tcp = require "silly.net.tcp"

local server = tcp.listen {
    addr = "127.0.0.1:8888",
    accept = function(conn)
        print("New connection from", conn.remoteaddr)
        while true do
            local data, err = conn:read("\n")
            if err then
                print("Client disconnected")
                break
            end

            conn:write("Echo: " .. data)
        end
        conn:close()
    end
}

print("Server listening on 127.0.0.1:8888")

Run the server:

./silly hello.lua

Test with telnet or netcat:

echo "Hello Silly\!" | nc localhost 8888

📊 Performance

Benchmarked on Intel Core i7-10700 @ 2.90GHz using redis-benchmark:

Test Throughput (req/s) Avg Latency P99 Latency
PING_INLINE 235,849 0.230ms 0.367ms
PING_MBULK 224,719 0.241ms 0.479ms

View Full Benchmark Results →

🎯 Examples

HTTP Server

local silly = require "silly"
local http = require "silly.net.http"

local server = http.listen {
    addr = "0.0.0.0:8080",
    handler = function(stream)
        local response_body = "Hello from Silly!"
        stream:respond(200, {
            ["content-type"] = "text/plain",
            ["content-length"] = #response_body,
        })
        stream:closewrite(response_body)
    end
}

print("HTTP server listening on http://0.0.0.0:8080")

WebSocket Chat

local silly = require "silly"
local http = require "silly.net.http"
local websocket = require "silly.net.websocket"

http.listen {
    addr = "127.0.0.1:8080",
    handler = function(stream)
        if stream.header["upgrade"] ~= "websocket" then
            stream:respond(404, {})
            stream:close("Not Found")
            return
        end
        local sock, err = websocket.upgrade(stream)
        if not sock then
            print("Upgrade failed:", err)
            return
        end
        print("New client connected")
        while true do
            local data, typ = sock:read()
            if not data or typ == "close" then
                break
            end

            if typ == "text" then
                sock:write("Echo: " .. data, "text")
            end
        end
        sock:close()
    end
}

print("WebSocket server listening on ws://0.0.0.0:8080")

MySQL Query

local mysql = require "silly.store.mysql"

local db = mysql.open {
    addr = "127.0.0.1:3306",
    user = "root",
    password = "password",
    database = "mydb",
    charset = "utf8mb4",
    max_open_conns = 10,
    max_idle_conns = 5,
}

local users, err = db:query("SELECT * FROM users WHERE age > ?", 18)
if users then
    for _, user in ipairs(users) do
        print(user.name, user.email)
    end
else
    print("Query failed:", err.message)
end

db:close()

For more examples, check out the tutorials in the documentation.

📚 Documentation

Comprehensive documentation is available at https://findstr.github.io/silly/

🏗️ Architecture

Silly uses a hybrid threading model for optimal performance:

┌─────────────────────────────────────────────────────┐
│                   Silly Framework                    │
├──────────────┬──────────────┬──────────────┬────────┤
│ Worker Thread│ Socket Thread│ Timer Thread │Monitor │
│  (Lua VM)    │ (epoll/kqueue│  (10ms res)  │ Thread │
│              │  /iocp)      │              │        │
│ • Coroutine  │ • I/O Events │ • Timers     │• Health│
│ • Business   │ • 65K conns  │ • Schedulers │  Check │
│   Logic      │              │              │        │
└──────────────┴──────────────┴──────────────┴────────┘

Key design principles:

  • Single-threaded business logic - No locks, no race conditions
  • Asynchronous I/O - Event-driven socket operations
  • Coroutine-based - Clean async code without callbacks

🔌 Core Modules

Module Description Documentation
silly.net TCP, UDP, HTTP, WebSocket, gRPC, TLS API
silly.store MySQL, Redis, Etcd API
silly.crypto AES, RSA, HMAC, Hash API
silly.sync Channel, Mutex, WaitGroup API
silly.security JWT authentication API
silly.metrics Prometheus metrics API
silly.logger Structured logging API

🛠️ Advanced Usage

Command Line Options

./silly main.lua [options]

Core Options:
  -h, --help                Display help message
  -v, --version             Show version
  -d, --daemon              Run as daemon

Logging:
  -p, --logpath PATH        Log file path
  -l, --loglevel LEVEL      Log level (debug/info/warn/error)
  -f, --pidfile FILE        PID file path

Custom Options:
  --key=value               Custom key-value pairs

Example with custom options:

./silly server.lua --port=8080 --workers=4 --env=production

Access in Lua:

local env = require "silly.env"
local port = env.get("port")        -- "8080"
local workers = env.get("workers")  -- "4"
local environment = env.get("env")  -- "production"

🧪 Testing

Run the complete test suite:

# Run all tests
make testall

# Run with address sanitizer (Linux/macOS)
make test

📦 Dependencies

Silly has minimal dependencies:

  • Lua 5.4 (embedded)
  • jemalloc (optional, for better memory allocation)
  • OpenSSL (optional, for TLS support)
  • zlib (embedded, for compression)

All dependencies are automatically built via Git submodules.

🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for details.

Development Setup

# Clone with submodules
git clone --recursive https://github.com/findstr/silly.git

# Build in debug mode
make test

# Format code
make fmt

📄 License

Silly is licensed under the MIT License.

🙏 Acknowledgments

  • Lua - The elegant scripting language
  • jemalloc - Scalable concurrent memory allocator
  • OpenSSL - Robust cryptography toolkit

📮 Contact & Community


About

A lightweight coroutine-based Lua network framework. TCP, TLS, WebSocket, gRPC, Redis, MySQL, Crypto, Prometheus, etcd v3.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.