{"id":37133790,"url":"https://github.com/lishank0119/fibril","last_synced_at":"2026-01-14T15:36:58.333Z","repository":{"id":276174858,"uuid":"928429703","full_name":"lishank0119/fibril","owner":"lishank0119","description":"Fibril is a fast and modular WebSocket server framework for Go, with sharding, pub/sub, and full client control.","archived":false,"fork":false,"pushed_at":"2025-05-16T15:35:39.000Z","size":74,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-16T16:27:30.512Z","etag":null,"topics":["backend","distributed-systems","fiber","fibril","framework","go","go-websocket","gofiber","golang","hub","pubsub","realtime","websocket","websocket-server"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lishank0119.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-06T16:17:36.000Z","updated_at":"2025-05-16T15:39:30.000Z","dependencies_parsed_at":"2025-02-06T18:32:24.437Z","dependency_job_id":"78a984e1-a298-457b-8b02-288a86138c0f","html_url":"https://github.com/lishank0119/fibril","commit_stats":null,"previous_names":["lishank0119/fibril"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/lishank0119/fibril","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lishank0119%2Ffibril","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lishank0119%2Ffibril/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lishank0119%2Ffibril/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lishank0119%2Ffibril/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lishank0119","download_url":"https://codeload.github.com/lishank0119/fibril/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lishank0119%2Ffibril/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28424374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T13:30:50.153Z","status":"ssl_error","status_checked_at":"2026-01-14T13:29:08.907Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","distributed-systems","fiber","fibril","framework","go","go-websocket","gofiber","golang","hub","pubsub","realtime","websocket","websocket-server"],"created_at":"2026-01-14T15:36:57.565Z","updated_at":"2026-01-14T15:36:58.315Z","avatar_url":"https://github.com/lishank0119.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Go Reference](https://pkg.go.dev/badge/github.com/lishank0119/fibril.svg)](https://pkg.go.dev/github.com/lishank0119/fibril)\n[![go.mod](https://img.shields.io/github/go-mod/go-version/lishank0119/fibril)](go.mod)\n[![Go Report Card](https://goreportcard.com/badge/github.com/lishank0119/fibril)](https://goreportcard.com/report/github.com/lishank0119/fibril)\n\n# Fibril - A WebSocket Library for Go\n\n[中文](README.zh-TW.md)\n\nFibril is a Go-based WebSocket library built on top of [GoFiber](https://github.com/gofiber/fiber) that provides a\nrobust and efficient way to handle WebSocket connections, messaging, and subscriptions. It supports features like\nmessage broadcasting, client management, and publishing messages to subscribed topics.\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n    - [Basic Example](#basic-example)\n    - [Fibril Function Examples](#fibril-function-examples)\n    - [Client Function Example](#client-function-example)\n- [Configuration Options](#configuration-options)\n- [Monitoring Topic State](#monitoring-topic-state)\n- [Contributions](#contributions)\n- [License](#license)\n\n## Features\n\n- 🚀 High-performance WebSocket server\n- 🔗 Built-in Pub/Sub system\n- ⚡ Sharding support for better scalability\n- 🔒 Client management with UUIDs\n- 🗂️ Custom key-value storage per client\n- 🧪 Monitoring: `ListTopics()` and `SubscriberCount(topic)` let you introspect pub/sub usage in real-time\n\n## Installation\n\n```bash\ngo get -u github.com/lishank0119/fibril\n```\n\n## Usage\n\n### Basic Example\n\n```go\npackage main\n\nimport (\n  \"github.com/gofiber/contrib/websocket\"\n  \"github.com/gofiber/fiber/v2\"\n  \"github.com/lishank0119/fibril\"\n  \"log\"\n)\n\nfunc main() {\n  app := fiber.New()\n\n  app.Use(\"/ws\", func(c *fiber.Ctx) error {\n    if websocket.IsWebSocketUpgrade(c) {\n      return c.Next()\n    }\n    return fiber.ErrUpgradeRequired\n  })\n\n  f := fibril.New(\n    fibril.WithShardCount(4),\n    fibril.WithMaxMessageSize(1024),\n  )\n\n  f.TextMessageHandler(func(client *fibril.Client, msg string) {\n    log.Printf(\"Received message from %s: %s\", client.GetUUID(), msg)\n    f.BroadcastText(\"Echo: \" + msg)\n  })\n\n  app.Get(\"/ws\", websocket.New(func(c *websocket.Conn) {\n    f.RegisterClient(c)\n  }))\n\n  log.Fatal(app.Listen(\":3000\"))\n}\n```\n\n### Fibril Function Examples\n\n### ForEachClient\n\nIterates over all active WebSocket clients and applies the given callback.\n\n```go\nf.ForEachClient(func(uuid string, client *fibril.Client) {\n// handle each client\n})\n```\n\n### ForEachClientWithContext\n\nIterates over all active clients and cancels early if the context is done.\n\n```go\nctx, cancel := context.WithTimeout(context.Background(), time.Second)\ndefer cancel()\n\nf.ForEachClientWithContext(ctx, func(uuid string, client *fibril.Client) {\n// handle each client\n})\n````\n\n### GetClient\n\nRetrieves a connected WebSocket client by UUID.\n\n```go\nclient, ok := f.GetClient(\"your-client-uuid\")\nif ok {\nclient.SendText(\"Hello!\")\n}\n```\n\n### ClientLen\n\nThe number of active WebSocket clients connected to the hub.\n\n```go\nf.ClientLen()\n```\n\n#### Publish\n\nPublishes a message to a specific topic.\n\n```go\nerr := f.Publish(\"server-time\", []byte(\"2024-02-09T15:04:05Z\"))\nif err != nil {\n\tlog.Println(\"Publish error:\", err)\n}\n```\n\n#### SendTextToClient\n\nSends a text message to a specific client.\n\n```go\nerr := f.SendTextToClient(\"client-uuid\", \"Hello, Client!\")\nif err != nil {\n\tlog.Println(\"Send error:\", err)\n}\n```\n\n#### SendBinaryToClient\n\nSends binary data to a specific client.\n\n```go\nerr := f.SendBinaryToClient(\"client-uuid\", []byte{0x01, 0x02, 0x03})\nif err != nil {\n\tlog.Println(\"Send error:\", err)\n}\n```\n\n#### BroadcastText\n\nBroadcasts a text message to all connected clients.\n\n```go\nf.BroadcastText(\"Hello, everyone!\")\n```\n\n#### BroadcastBinary\n\nBroadcasts binary data to all connected clients.\n\n```go\nf.BroadcastBinary([]byte{0x10, 0x20, 0x30})\n```\n\n#### RegisterClient\n\nRegisters a new WebSocket client.\n\n```go\napp.Get(\"/ws\", websocket.New(func(c *websocket.Conn) {\n\tf.RegisterClient(c)\n}))\n```\n\n#### RegisterClientWithKeys\n\nRegisters a new WebSocket client with custom key-value pairs.\n\n```go\napp.Get(\"/ws/:id\", websocket.New(func(c *websocket.Conn) {\n\tf.RegisterClientWithKeys(c, map[any]any{\"id\": c.Params(\"id\")})\n}))\n```\n\n### DisconnectAll\n\nDisconnects all connected WebSocket clients with a given close message.\n\n```go\nf.DisconnectAll(\"Server restarting\")\n```\n\n#### DisconnectClient\n\nDisconnects a specific client by UUID.\n\n```go\nerr := f.DisconnectClient(\"Goodbye!\", \"client-uuid\")\nif err != nil {\n\tlog.Println(\"Disconnect error:\", err)\n}\n```\n\n#### DisconnectClientFilter\n\nDisconnects clients based on a filter function.\n\n```go\nf.DisconnectClientFilter(\"Maintenance\", func(c *fibril.Client) bool {\n\treturn c.GetKey(\"role\") == \"guest\"\n})\n```\n\n#### Available Handlers\n\n- **ConnectHandler**: Handles client connection.\n\n```go\nf.ConnectHandler(func(client *fibril.Client) {\n\tlog.Println(\"Client connected:\", client.GetUUID())\n})\n```\n\n- **DisconnectHandler**: Handles client disconnection.\n\n```go\nf.DisconnectHandler(func(client *fibril.Client) {\n\tlog.Println(\"Client disconnected:\", client.GetUUID())\n})\n```\n\n- **ErrorHandler**: Handles errors that occur within a client connection.\n\n```go\nf.ErrorHandler(func(client *fibril.Client, err error) {\n\tlog.Println(\"Error for client\", client.GetUUID(), \":\", err)\n})\n```\n\n- **TextMessageHandler**: Handles text messages.\n\n```go\nf.TextMessageHandler(func(client *fibril.Client, msg string) {\n\tlog.Println(\"Received text message:\", msg)\n})\n```\n\n- **BinaryMessageHandler**: Handles binary messages.\n\n```go\nf.BinaryMessageHandler(func(client *fibril.Client, msg []byte) {\n\tlog.Println(\"Received binary message:\", msg)\n})\n```\n\n- **PongHandler**: Handles pong responses from clients.\n\n```go\nf.PongHandler(func(client *fibril.Client) {\n\tlog.Println(\"Pong received from:\", client.GetUUID())\n})\n```\n\n### Client Function Example\n\n#### GetUUID\nGets the unique identifier (UUID) of the client.\n\n```go\nuuid := client.GetUUID()\nlog.Printf(\"Client UUID: %s\", uuid)\n```\n\n#### Subscribe\n\nSubscribes the client to a specific topic with a handler function.\n\n```go\nclient.Subscribe(\"topic-name\", func(msg []byte) {\n\tlog.Printf(\"Received message for topic: %s\", string(msg))\n})\n```\n\n#### SendText\n\nSends a text message to the client.\n\n```go\nerr := client.SendText(\"Hello, Client!\")\nif err != nil {\n\tlog.Println(\"Send error:\", err)\n}\n```\n\n#### SendBinary\n\nSends binary data to the client.\n\n```go\nerr := client.SendBinary([]byte{0x01, 0x02, 0x03})\nif err != nil {\n\tlog.Println(\"Send error:\", err)\n}\n```\n\n#### Disconnect\n\nDisconnects the client with a custom message.\n\n```go\nclient.Disconnect(\"Goodbye!\")\n```\n\n#### StoreKey\n\nStores a custom key-value pair associated with the client.\n\n```go\nclient.StoreKey(\"role\", \"admin\")\n```\n\n#### DeleteKey\n\nDeletes a custom key-value pair associated with the client.\n\n```go\nclient.DeleteKey(\"role\")\n```\n\n#### GetKey\n\nRetrieves the value of a key associated with the client.\n\n```go\nrole, ok := client.GetKey(\"role\")\nif ok {\n\tlog.Printf(\"Client role: %v\", role)\n}\n```\n\n## Configuration Options\n\nYou can customize the following options when initializing `Fibril`:\n\n- **ShardCount**: The number of shards for managing clients (default: 16).\n- **MaxMessageSize**: The maximum size of incoming messages in bytes (default: 512).\n- **MessageBufferSize**: The size of the message buffer (default: 256).\n- **WriteWait**: The duration to wait before closing the write connection (default: 10 seconds).\n- **PongWait**: The duration to wait for a pong response from the client (default: 60 seconds).\n- **PingPeriod**: The interval to send ping messages (default: 54 seconds).\n\n### Example:\n\n```go\nf := fibril.New(\n    fibril.WithShardCount(20),\n    fibril.WithMaxMessageSize(1024),\n    fibril.WithMessageBufferSize(512),\n    fibril.WithWriteWait(15 * time.Second),\n    fibril.WithPongWait(30 * time.Second),\n    fibril.WithPingPeriod(25 * time.Second),\n)\n```\n\n## Monitoring Topic State\n\nFibril exposes methods to monitor internal pub/sub state:\n\n```go\nfibril.ListTopics()           // returns []string\nfibril.SubscriberCount(\"X\")   // returns int\n```\n\n## Contributions\n\nFeel free to contribute to the project by forking it, making improvements, or submitting bug fixes via pull requests.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flishank0119%2Ffibril","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flishank0119%2Ffibril","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flishank0119%2Ffibril/lists"}