{"id":41996693,"url":"https://github.com/yddeng/dnet","last_synced_at":"2026-01-26T01:06:04.666Z","repository":{"id":53068837,"uuid":"179009381","full_name":"yddeng/dnet","owner":"yddeng","description":"tcp、websocket、 rpc","archived":false,"fork":false,"pushed_at":"2025-05-22T01:58:33.000Z","size":210,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-05-22T02:38:19.332Z","etag":null,"topics":["net","rpc","tcp","websocket"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yddeng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-02T06:01:47.000Z","updated_at":"2025-05-22T01:58:36.000Z","dependencies_parsed_at":"2022-08-26T06:01:22.821Z","dependency_job_id":null,"html_url":"https://github.com/yddeng/dnet","commit_stats":null,"previous_names":["tagdong/dnet"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yddeng/dnet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yddeng%2Fdnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yddeng%2Fdnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yddeng%2Fdnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yddeng%2Fdnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yddeng","download_url":"https://codeload.github.com/yddeng/dnet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yddeng%2Fdnet/sbom","scorecard":{"id":865622,"data":{"date":"2025-07-07","repo":{"name":"github.com/yddeng/dnet","commit":"ee1f7b27bd287e6a47e5c21872b92bdf34f9c904"},"scorecard":{"version":"v5.2.1-18-gbb9c347d","commit":"bb9c347dff6349d986baab6578a46d68a5524c62"},"score":3,"checks":[{"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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#packaging"}},{"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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#pinned-dependencies"}},{"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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":3,"reason":"4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#dangerous-workflow"}},{"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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/27 approved changesets -- score normalized to 0","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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#code-review"}},{"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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#cii-best-practices"}},{"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/bb9c347dff6349d986baab6578a46d68a5524c62/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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#vulnerabilities"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#license"}},{"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/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#security-policy"}},{"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/bb9c347dff6349d986baab6578a46d68a5524c62/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/bb9c347dff6349d986baab6578a46d68a5524c62/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 4 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/bb9c347dff6349d986baab6578a46d68a5524c62/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-24T02:37:27.137Z","repository_id":53068837,"created_at":"2025-08-24T02:37:27.137Z","updated_at":"2025-08-24T02:37:27.137Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28763132,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T00:37:26.264Z","status":"ssl_error","status_checked_at":"2026-01-26T00:37:25.959Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["net","rpc","tcp","websocket"],"created_at":"2026-01-26T01:06:04.095Z","updated_at":"2026-01-26T01:06:04.657Z","avatar_url":"https://github.com/yddeng.png","language":"Go","readme":"## dnet\n\n一个简单的 `tcp`、`websocket` 的封装\n\n\n### Session\n\n```\ntype Session interface {\n\t// connection\n\tNetConn() interface{}\n\t\n\t// RemoteAddr returns the remote network address.\n\tRemoteAddr() net.Addr\n\t\n\t// LocalAddr returns the local network address.\n\tLocalAddr() net.Addr\n\t\n\t// Send data will be encoded by the encoder and sent\n\tSend(o interface{}) error\n\t\n\t// SetContext binding session data\n\tSetContext(ctx interface{})\n\t\n\t// Context returns binding session data\n\tContext() interface{}\n\t\n\t// Close closes the session.\n\tClose(reason error)\n\t\n\t// IsClosed returns has it been closed\n\tIsClosed() bool\n}\n```\n\n### Functional options for session\n```\n// Options contains all options which will be applied when instantiating a session.\ntype Options struct {\n\t// when the send channel is full, BlockSend will block if it is true.\n\t// or it return queue full error code, if BlockSend is false.\n\t// it default is false\n\tBlockSend bool\n\n\t// capacity of the send channel. default net.defSendChannelSize\n\tSendChannelSize int\n\n\t// the deadline for read\n\tReadTimeout time.Duration\n\n\t// the deadline for write\n\tWriteTimeout time.Duration\n\n\t// session will call the MsgCallback,if it has a message\n\tMsgCallback func(session Session, message interface{})\n\n\t// session will call the ErrorCallback,if it has a error\n\tErrorCallback func(session Session, err error)\n\n\t// session will call the CloseCallback,if it is closed\n\tCloseCallback func(session Session, reason error)\n\n\t// encoder and decoder\n\tCodec Codec\n}\n\n// WithOptions accepts the whole options config.\nfunc WithOptions(option *Options) Option {\n\treturn func(opt *Options) {\n\t\topt = option\n\t}\n}\n\n// WithBlockSend indicates whether it should block when the send channel full.\nfunc WithBlockSend(bs bool) Option {\n\treturn func(opt *Options) {\n\t\topt.BlockSend = bs\n\t}\n}\n\n// WithSendChannelSize sets capacity of the send channel .\nfunc WithSendChannelSize(size int) Option {\n\treturn func(opt *Options) {\n\t\topt.SendChannelSize = size\n\t}\n}\n\n// WithMessageCallback sets message callback.\nfunc WithMessageCallback(msgCb func(session Session, message interface{})) Option {\n\treturn func(opt *Options) {\n\t\topt.MsgCallback = msgCb\n\t}\n}\n\n// WithErrorCallback sets error callback.\nfunc WithErrorCallback(errCb func(session Session, err error)) Option {\n\treturn func(opt *Options) {\n\t\topt.ErrorCallback = errCb\n\t}\n}\n\n// WithTimeout sets the deadline of read/write.\nfunc WithTimeout(readTimeout, writeTimeout time.Duration) Option {\n\treturn func(opt *Options) {\n\t\topt.ReadTimeout = readTimeout\n\t\topt.WriteTimeout = writeTimeout\n\t}\n}\n\n// WithCodec sets codec.\nfunc WithCodec(codec Codec) Option {\n\treturn func(opt *Options) {\n\t\topt.Codec = codec\n\t}\n}\n\n// WithCloseCallback sets close callback.\nfunc WithCloseCallback(closeCallback func(session Session, reason error)) Option {\n\treturn func(opt *Options) {\n\t\topt.CloseCallback = closeCallback\n\t}\n}\n```\n\n#### 编码(Codec)\n\n自定义编解码器，实现如下接口：\n\n```\n//编解码器\ntype Codec interface {\n\t//编码\n\tEncode(interface{}) ([]byte, error)\n\t//解码\n\tDecode(reader io.Reader) (interface{}, error)\n}\n```\n\n通过`WithCodec`设置会话的编解码器\n\n`tcp`默认的编码器，实现数据的沾包、分包。\n\n### acceptor\n\n```\ntype Acceptor interface {\n\t// Serve listen and serve with AcceptorHandler\n\tServe(handler AcceptorHandler) error\n\t// ServeFunc listen and serve with AcceptorHandlerFunc\n\tServeFunc(handler AcceptorHandlerFunc) error\n\t// Stop stop the acceptor\n\tStop()\n\t// Addr returns address of the listener\n\tAddr() net.Addr\n}\n```\n\n`Serve` 启动服务，需要传入一个`AcceptorHandle`. \n\n```\n// AcceptorHandle type interface\ntype AcceptorHandler interface {\n\t// handler to invokes\n\tOnConnection(conn NetConn)\n}\n\ntype AcceptorHandlerFunc func(conn NetConn)\n\nfunc (handler AcceptorHandlerFunc) OnConnection(conn NetConn) {\n\t// handler to invokes\n\thandler(conn)\n}\n\n// HandleFunc returns AcceptorHandlerFunc with the handler function.\nfunc HandleFunc(handler func(conn NetConn)) AcceptorHandlerFunc {\n\treturn handler\n}\n```\n\n可通过`dnet`下`HandleFunc`将一个`func(conn NetConn)`转成`AcceptorHandle`。调用方式如下：\n\n```\nServeTCP(\":4522\", HandleFunc(func(conn NetConn) {\n    // do something\n}))\n```\n\n#### example\n\n```\ntype testTCPHandler struct{}\n\nfunc (this *testTCPHandler) OnConnection(conn NetConn) {\n\tfmt.Println(\"new Conn\", conn.RemoteAddr())\n\tsession := NewTCPSession(conn,\n\t\tWithCloseCallback(func(session Session, reason error) {\n\t\t\tfmt.Println(session.RemoteAddr(), reason, \"ss close\")\n\t\t}),\n\t\tWithMessageCallback(func(session Session, message interface{}) {\n\t\t\tfmt.Println(\"ss\", message)\n\t\t}),\n\t\tWithErrorCallback(func(session Session, err error) {\n\t\t\tfmt.Println(\"ss error\", err)\n\t\t}))\n\ttime.Sleep(time.Millisecond * 200)\n\tfmt.Println(session.Send([]byte{4, 3, 2, 1}))\n\tfmt.Println(session.Send([]byte{4, 3, 2, 1}))\n}\n\nfunc TestNewTCPSession(t *testing.T) {\n\tgo func() {\n\t\tServeTCP(\":4522\", \u0026testTCPHandler{})\n\t}()\n\n\ttime.Sleep(time.Millisecond * 100)\n\n\tconn, err := DialTCP(\"127.0.0.1:4522\", 0)\n\tif err != nil {\n\t\tfmt.Println(\"dialTcp\", err)\n\t\treturn\n\t}\n\n\tsession := NewTCPSession(conn,\n\t\tWithCloseCallback(func(session Session, reason error) {\n\t\t\tfmt.Println(session.RemoteAddr(), reason, \"cc close\")\n\t\t}),\n\t\tWithMessageCallback(func(session Session, message interface{}) {\n\t\t\tfmt.Println(\"cc\", message)\n\t\t}),\n\t\tWithErrorCallback(func(session Session, err error) {\n\t\t\tfmt.Println(\"cc error\", err)\n\t\t}))\n\n\tfmt.Println(session.Send([]byte{1, 2, 3, 4}))\n\tfmt.Println(session.Send([]byte{1, 2, 3, 4, 5}))\n\tfmt.Println(session.Send([]byte{1, 2, 3, 4, 5, 6}))\n\t//fmt.Println(session.Send(123))\n\n\ttime.Sleep(time.Second)\n\tfmt.Println(\" ------- close ----------\")\n\tsession.Close(nil)\n\tfmt.Println(session.Send([]byte{1, 2, 3, 4}))\n\ttime.Sleep(time.Second)\n\n}\n```\n\n**echo 示例项目 examples/cs**\n\n**rpc 示例 example/rpc**\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyddeng%2Fdnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyddeng%2Fdnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyddeng%2Fdnet/lists"}