{"id":50242423,"url":"https://github.com/dev-cloverlab/go-message-broadcaster","last_synced_at":"2026-05-26T21:36:16.028Z","repository":{"id":91935561,"uuid":"120855856","full_name":"dev-cloverlab/go-message-broadcaster","owner":"dev-cloverlab","description":"bidirectional message communication middleware that composed on server-client architecture","archived":false,"fork":false,"pushed_at":"2018-07-02T06:49:08.000Z","size":22,"stargazers_count":6,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2026-05-26T21:35:53.585Z","etag":null,"topics":["go","realtime-messaging","server-client-communication","websocket"],"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/dev-cloverlab.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}},"created_at":"2018-02-09T04:21:38.000Z","updated_at":"2018-10-05T13:03:31.000Z","dependencies_parsed_at":"2024-06-20T17:30:03.027Z","dependency_job_id":null,"html_url":"https://github.com/dev-cloverlab/go-message-broadcaster","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dev-cloverlab/go-message-broadcaster","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cloverlab%2Fgo-message-broadcaster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cloverlab%2Fgo-message-broadcaster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cloverlab%2Fgo-message-broadcaster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cloverlab%2Fgo-message-broadcaster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dev-cloverlab","download_url":"https://codeload.github.com/dev-cloverlab/go-message-broadcaster/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-cloverlab%2Fgo-message-broadcaster/sbom","scorecard":{"id":336497,"data":{"date":"2025-08-11","repo":{"name":"github.com/dev-cloverlab/go-message-broadcaster","commit":"8e16d62c530ddaf71f681417e88aee78d2239046"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":2,"reason":"Found 4/18 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 17 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T04:51:52.090Z","repository_id":91935561,"created_at":"2025-08-18T04:51:52.090Z","updated_at":"2025-08-18T04:51:52.090Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33540615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"ssl_error","status_checked_at":"2026-05-26T15:22:15.568Z","response_time":63,"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":["go","realtime-messaging","server-client-communication","websocket"],"created_at":"2026-05-26T21:35:55.914Z","updated_at":"2026-05-26T21:36:16.014Z","avatar_url":"https://github.com/dev-cloverlab.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-message-broadcaster\n\n[![GitHub release](https://img.shields.io/github/release/dev-cloverlab/go-message-broadcaster.svg?style=flat-square)](https://github.com/dev-cloverlab/go-message-broadcaster)\n[![license](https://img.shields.io/github/license/dev-cloverlab/go-message-broadcaster.svg?style=flat-square)](https://github.com/dev-cloverlab/go-message-broadcaster)\n\ngo-message-broadcaster is bidirectional message communication middleware that composed on server-client architecture.  \nThis can be used on any connection interfaces as you like.  \n\n# WebSocket example\n\nThis is message broadcasting example using WebSocket connection.  \nFollowing code is a quote from example/websocket/main.go:\n\n```go\nfunc main() {\n\tport := flag.Int(\"p\", 9218, \"websocket listen port\")\n\tendpoint := flag.String(\"e\", \"/\", \"websocket application endpoint path\")\n\tflag.Parse()\n\n    // Create message handlers for each message \n    handlers := broadcaster.MessageHandlers{\n\t\t1: func(msg *broadcaster.RequestMessage, c context.Context) (*broadcaster.ResponseMessage, error) {\n            // Create broadcasting message object (This is simple echo handler).\n\t\t\treturn broadcaster.NewResponseMessage(broadcaster.All, msg.Body), nil\n\t\t},\n\t}\n\n    // Initialize the server and listen all clients\n\tsv := broadcaster.NewServer(context.Background(), handlers)\n\tgo sv.Listen()\n\n\thttp.Handle(*endpoint, websocket.Handler(func(ws *websocket.Conn) {\n        // Add new client to server and listen ws connection\n\t\tsv.NewClient(\u0026Conn{ws: ws}).Listen()\n\t}))\n\n\tif err := http.ListenAndServe(fmt.Sprintf(\":%d\", *port), nil); err != nil {\n\t\tpanic(err)\n\t}\n}\n```\n\nStart the server:\n\n```\n% go run example/websocket/main.go\n```\n\nConnect to the server from two or more terminal client using `wscat`:\n\n```\n% wscat -c ws://localhost:9218/ -o localhost:9218\nconnected (press CTRL+C to quit)\n\u003c {\"EventType\":1,\"ClientID\":\"e68e76f0-7725-3f76-d9fb-bb4a72ca2121\"}\n\u003e \n```\n\nSend messages from each others:\n\n```\n\u003e {\"HandlerID\": 1, \"Body\":\"SGVsbG8sIHdvcmxkIQ==\"}\n\u003c {\"SenderID\":\"98f1088e-1e28-3cec-c73a-ab7e4c678149\",\"HandlerID\":1,\"CastType\":1,\"CastFor\":null,\"Body\":\"SGVsbG8sIHdvcmxkIQ==\"}\n```\n\n# Connection interface\n\nFor using go-message-broadcaster, you need to implement the following Conn interface:\n\n```go\ntype Conn interface {\n\tSendMessage(*ResponseMessage) error\n\tSendEvent(*EventMessage) error\n\tReceive() (*RequestMessage, error)\n\tClose() error\n}\n```\n\nSee the example: example/websocket/main.go\n\n# Message and Event\n\ngo-message-broadcaster has three message types `RequestMessage`, `ResponseMessage` and `EventMessage`.  \n\n## RequestMessage \n\n```go\ntype RequestMessage struct {\n\tSenderID  ClientID\n\tHandlerID MessageHandlerID\n\tBody      []byte\n}\n```\n\nRequestMessage is the type when sending from client to server.  \n\n- `SenderID` is the client ID that was granted by the server.  \n- `HandlerID` is message handler ID of the process that corresponding for each message as you defined.  \n- `Body` is the request body\n\nYou don't need to set the `SenderID`, this is granted by the system automatically.   \n\n## ResponseMessage\n\n```go\ntype ResponseMessage struct {\n\tSenderID  ClientID\n\tHandlerID MessageHandlerID\n\tCastType  CastType\n\tCastFor   []ClientID\n\tBody      []byte\n}\n```\n\nResponseMessage is the type when sending from server to client.  \n\n- `SenderID` is the sender client ID of the request message.  \n- `HanderID` is the executed handler ID.   \n- `Body` is the response binary that was formatted as you like.\n\n`CastType` is message broadcasting type:  \n\n- All - The message will be sent for all connected clients.\n- Self - The message will be sent for only sender client.\n- Exclusive - The message will be sent for only clients that specified `CastFor` slice.\n\nYou don't need to set the `SenderID` and `HandlerID`, these are granted by the system automatically.  \n\n## EventMessage\n\n```go\ntype EventMessage struct {\n\tEventType EventType\n\tClientID  ClientID\n}\n```\n\nEventMessage is the type when sending from server to client.  \nThere are following types of events:\n\n- OnAddClient - emit when new client adding to the server\n- OnDelClient - emit when client deleting from server\n\n# Handlers \n\ngo-message-broadcaster can define several handlers for each message and event as following types:\n\n```go\ntype MessageHandlerID int\ntype MessageHandler func(msg *RequestMessage, ctx context.Context) (*ResponseMessage, error)\ntype MessageHandlers map[MessageHandlerID]MessageHandler\n\ntype EventType int\ntype EventHandler func(msg *EventMessage, ctx context.Context) (*ResponseMessage, error)\ntype EventHandlers map[EventType]EventHandler\n\n```\n\nThese handlers are set when the server initialized.  \nThese message handlers are called when the server received the request from clients.  \nThese event handlers are called when the client adding or deleting.  \n\n# Contribution\n\n1. Fork ([https://github.com/dev-cloverlab/go-message-broadcaster/fork](https://github.com/dev-cloverlab/go-message-broadcaster/fork))\n1. Create a feature branch\n1. Commit your changes\n1. Rebase your local changes against the master branch\n1. Run test suite with the `go test ./...` command and confirm that it passes\n1. Run `gofmt -s`\n1. Create a new Pull Request\n\n# Author\n\n[@hatajoe](https://twitter.com/hatajoe)\n\n# Licence\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-cloverlab%2Fgo-message-broadcaster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdev-cloverlab%2Fgo-message-broadcaster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-cloverlab%2Fgo-message-broadcaster/lists"}