{"id":13413580,"url":"https://github.com/zubairhamed/canopus","last_synced_at":"2026-01-26T14:07:39.050Z","repository":{"id":27756086,"uuid":"31244198","full_name":"zubairhamed/canopus","owner":"zubairhamed","description":"CoAP Client/Server implementing RFC 7252 for the Go Language","archived":false,"fork":false,"pushed_at":"2018-03-25T17:28:53.000Z","size":3244,"stargazers_count":156,"open_issues_count":43,"forks_count":39,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-08-13T20:17:32.189Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"AOEpeople/formhandler","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zubairhamed.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}},"created_at":"2015-02-24T04:12:20.000Z","updated_at":"2024-12-27T14:51:04.000Z","dependencies_parsed_at":"2022-09-01T23:10:59.444Z","dependency_job_id":null,"html_url":"https://github.com/zubairhamed/canopus","commit_stats":null,"previous_names":["zubairhamed/goap"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zubairhamed/canopus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zubairhamed%2Fcanopus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zubairhamed%2Fcanopus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zubairhamed%2Fcanopus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zubairhamed%2Fcanopus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zubairhamed","download_url":"https://codeload.github.com/zubairhamed/canopus/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zubairhamed%2Fcanopus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28780213,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T13:55:28.044Z","status":"ssl_error","status_checked_at":"2026-01-26T13:55:26.068Z","response_time":59,"last_error":"SSL_read: 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":[],"created_at":"2024-07-30T20:01:43.691Z","updated_at":"2026-01-26T14:07:39.021Z","avatar_url":"https://github.com/zubairhamed.png","language":"Go","funding_links":[],"categories":["Networking","Libraries","网络相关库","网络","\u003cspan id=\"网络-networking\"\u003e网络 Networking\u003c/span\u003e","Relational Databases","網絡"],"sub_categories":["Uncategorized","Transliteration","Advanced Console UIs","Go","暂未分类这些库被放在这里是因为其他类别似乎都不适合。","音译","交流","暂未分类","Strings","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","高級控制台界面","高级控制台界面"],"readme":"# Canopus\n\n[![GoDoc](https://godoc.org/github.com/zubairhamed/canopus?status.svg)](https://godoc.org/github.com/zubairhamed/canopus)\n[![Build Status](https://drone.io/github.com/zubairhamed/canopus/status.png?)](https://drone.io/github.com/zubairhamed/canopus/latest)\n[![Coverage Status](https://coveralls.io/repos/zubairhamed/canopus/badge.svg?branch=master)](https://coveralls.io/r/zubairhamed/canopus?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/zubairhamed/canopus)](https://goreportcard.com/report/github.com/zubairhamed/canopus)\n\n#### Canopus is a client/server implementation of the [Constrained Application Protocol (CoAP)][RFC7252]\n[RFC7252]: http://tools.ietf.org/html/rfc7252\n\n## Updates\n#### 25.11.2016\nI've added basic dTLS Support based on [Julien Vermillard's][JVERMILLARD] [implementation][NATIVEDTLS]. Thanks Julien! It should now support PSK-based authentication.\nI've also gone ahead and refactored the APIs to make it that bit more Go idiomatic.\n[JVERMILLARD]: https://github.com/jvermillard\n[NATIVEDTLS]: https://github.com/jvermillard/nativedtls\n\n## Building and running\n1. git submodule update --init --recursive\n2. cd openssl\n3. ./config \u0026\u0026 make\n4. You should then be able to run the examples in the /examples folder\n\n#### Simple Example\n```go\n\t// Server\n\t// See /examples/simple/server/main.go\n\tserver := canopus.NewServer()\n\n\tserver.Get(\"/hello\", func(req canopus.Request) canopus.Response {\n\t\tmsg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)\n\t\tmsg.SetStringPayload(\"Acknowledged: \" + req.GetMessage().GetPayload().String())\n\n\t\tres := canopus.NewResponse(msg, nil)\n\t\treturn res\n\t})\n\n\tserver.ListenAndServe(\":5683\")\n\n\t// Client\n\t// See /examples/simple/client/main.go\n\tconn, err := canopus.Dial(\"localhost:5683\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\treq := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID()).(*canopus.CoapRequest)\n\treq.SetStringPayload(\"Hello, canopus\")\n\treq.SetRequestURI(\"/hello\")\n\n\tresp, err := conn.Send(req)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\tfmt.Println(\"Got Response:\" + resp.GetMessage().GetPayload().String())\n```\n\n#### Observe / Notify\n```go\n\t// Server\n\t// See /examples/observe/server/main.go\n\tserver := canopus.NewServer()\n\tserver.Get(\"/watch/this\", func(req canopus.Request) canopus.Response {\n\t\tmsg := canopus.NewMessageOfType(canopus.MessageAcknowledgment, req.GetMessage().GetMessageId(), canopus.NewPlainTextPayload(\"Acknowledged\"))\n\t\tres := canopus.NewResponse(msg, nil)\n\n\t\treturn res\n\t})\n\n\tticker := time.NewTicker(3 * time.Second)\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase \u003c-ticker.C:\n\t\t\t\tchangeVal := strconv.Itoa(rand.Int())\n\t\t\t\tfmt.Println(\"[SERVER \u003c\u003c ] Change of value --\u003e\", changeVal)\n\n\t\t\t\tserver.NotifyChange(\"/watch/this\", changeVal, false)\n\t\t\t}\n\t\t}\n\t}()\n\n\tserver.OnObserve(func(resource string, msg canopus.Message) {\n\t\tfmt.Println(\"[SERVER \u003c\u003c ] Observe Requested for \" + resource)\n\t})\n\n\tserver.ListenAndServe(\":5683\")\n\n\t// Client\n\t// See /examples/observe/client/main.go\n\tconn, err := canopus.Dial(\"localhost:5683\")\n\n\ttok, err := conn.ObserveResource(\"/watch/this\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\tobsChannel := make(chan canopus.ObserveMessage)\n\tdone := make(chan bool)\n\tgo conn.Observe(obsChannel)\n\n\tnotifyCount := 0\n\tfor {\n\t\tselect {\n\t\tcase obsMsg, _ := \u003c-obsChannel:\n\t\t\tif notifyCount == 5 {\n\t\t\t\tfmt.Println(\"[CLIENT \u003e\u003e ] Canceling observe after 5 notifications..\")\n\t\t\t\tgo conn.CancelObserveResource(\"watch/this\", tok)\n\t\t\t\tgo conn.StopObserve(obsChannel)\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\tnotifyCount++\n\t\t\t\t// msg := obsMsg.Msg\\\n\t\t\t\tresource := obsMsg.GetResource()\n\t\t\t\tval := obsMsg.GetValue()\n\n\t\t\t\tfmt.Println(\"[CLIENT \u003e\u003e ] Got Change Notification for resource and value: \", notifyCount, resource, val)\n\t\t\t}\n\t\t}\n\t}\n```\n\n### dTLS with PSK\n```go\n\t// Server\n\t// See /examples/dtls/simple-psk/server/main.go\n\tserver := canopus.NewServer()\n\n\tserver.Get(\"/hello\", func(req canopus.Request) canopus.Response {\n\t\tmsg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)\n\t\tmsg.SetStringPayload(\"Acknowledged: \" + req.GetMessage().GetPayload().String())\n\t\tres := canopus.NewResponse(msg, nil)\n\n\t\treturn res\n\t})\n\n\tserver.HandlePSK(func(id string) []byte {\n\t\treturn []byte(\"secretPSK\")\n\t})\n\n\tserver.ListenAndServeDTLS(\":5684\")\n\n\t// Client\n\t// See /examples/dtls/simple-psk/client/main.go\n\tconn, err := canopus.DialDTLS(\"localhost:5684\", \"canopus\", \"secretPSK\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\treq := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID())\n\treq.SetStringPayload(\"Hello, canopus\")\n\treq.SetRequestURI(\"/hello\")\n\n\tresp, err := conn.Send(req)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\tfmt.Println(\"Got Response:\" + resp.GetMessage().GetPayload().String())\n```\n\n#### CoAP-CoAP Proxy\n```go\n\t// Server\n\t// See /examples/proxy/coap/server/main.go\n\tserver := canopus.NewServer()\n\n\tserver.Get(\"/proxycall\", func(req canopus.Request) canopus.Response {\n\t\tmsg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)\n\t\tmsg.SetStringPayload(\"Data from :5685 -- \" + req.GetMessage().GetPayload().String())\n\t\tres := canopus.NewResponse(msg, nil)\n\n\t\treturn res\n\t})\n\tserver.ListenAndServe(\":5685\")\n\n\t// Proxy Server\n\t// See /examples/proxy/coap/proxy/main.go\n\tserver := canopus.NewServer()\n\tserver.ProxyOverCoap(true)\n\n\tserver.Get(\"/proxycall\", func(req canopus.Request) canopus.Response {\n\t\tcanopus.PrintMessage(req.GetMessage())\n\t\tmsg := canopus.ContentMessage(req.GetMessage().GetMessageId(), canopus.MessageAcknowledgment)\n\t\tmsg.SetStringPayload(\"Acknowledged: \" + req.GetMessage().GetPayload().String())\n\t\tres := canopus.NewResponse(msg, nil)\n\n\t\treturn res\n\t})\n\tserver.ListenAndServe(\":5683\")\n\n\t// Client\n\t// See /examples/proxy/coap/client/main.go\n\tconn, err := canopus.Dial(\"localhost:5683\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\treq := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID())\n\treq.SetProxyURI(\"coap://localhost:5685/proxycall\")\n\n\tresp, err := conn.Send(req)\n\tif err != nil {\n\t\tprintln(\"err\", err)\n\t}\n\tcanopus.PrintMessage(resp.GetMessage())\n```\n\n#### CoAP-HTTP Proxy\n```go\n\t// Server\n\t// See /examples/proxy/http/server/main.go\n\tserver := canopus.NewServer()\n\tserver.ProxyOverHttp(true)\n\n\tserver.ListenAndServe(\":5683\")\n\n\t// Client\n\t// See /examples/proxy/http/client/main.go\n\tconn, err := canopus.Dial(\"localhost:5683\")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\n\treq := canopus.NewRequest(canopus.MessageConfirmable, canopus.Get, canopus.GenerateMessageID())\n\treq.SetProxyURI(\"https://httpbin.org/get\")\n\n\tresp, err := conn.Send(req)\n\tif err != nil {\n\t\tprintln(\"err\", err)\n\t}\n\tcanopus.PrintMessage(resp.GetMessage())\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzubairhamed%2Fcanopus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzubairhamed%2Fcanopus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzubairhamed%2Fcanopus/lists"}