{"id":18515133,"url":"https://github.com/billziss-gh/netchan","last_synced_at":"2025-04-09T06:34:47.723Z","repository":{"id":57501506,"uuid":"101568439","full_name":"billziss-gh/netchan","owner":"billziss-gh","description":"Natural network channels for Go - netchan can marshal Go channels","archived":false,"fork":false,"pushed_at":"2017-10-02T23:53:21.000Z","size":197,"stargazers_count":20,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-24T01:01:34.512Z","etag":null,"topics":["go","golang","golang-library"],"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/billziss-gh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-27T17:23:46.000Z","updated_at":"2024-03-20T16:40:05.000Z","dependencies_parsed_at":"2022-09-19T08:50:14.078Z","dependency_job_id":null,"html_url":"https://github.com/billziss-gh/netchan","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billziss-gh%2Fnetchan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billziss-gh%2Fnetchan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billziss-gh%2Fnetchan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/billziss-gh%2Fnetchan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/billziss-gh","download_url":"https://codeload.github.com/billziss-gh/netchan/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247993624,"owners_count":21030043,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","golang","golang-library"],"created_at":"2024-11-06T15:46:39.397Z","updated_at":"2025-04-09T06:34:42.714Z","avatar_url":"https://github.com/billziss-gh.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# netchan - Natural network channels for Go\n\n[![Travis CI](https://img.shields.io/travis/billziss-gh/netchan.svg)](https://travis-ci.org/billziss-gh/netchan)\n[![GoDoc](https://godoc.org/github.com/billziss-gh/netchan/netchan?status.svg)](https://godoc.org/github.com/billziss-gh/netchan/netchan)\n\nPackage netchan enables Go channels to be used over the network.\nMessages sent over a channel on one machine will be received by a\nchannel of the same type on a different machine. This includes messages\nthat contain channels (i.e. it is possible to \"marshal\" channels using\nthis package).\n\nThere are two fundamental concepts in netchan: \"exposing\" and\n\"binding\". A channel that is exposed, becomes associated with a\npublic name (\"ID\") and available to receive messages. A channel on a\ndifferent machine may then be bound to the exposed channel.\nMessages sent to the bound channel will be transported over a\nnetwork transport and will become available to be received by the\nexposed channel. Effectively the two channels become the endpoints of\na unidirectional network link.\n\n## Exposing a channel\n\nIn order to expose a channel under an ID the Expose() function must be\nused; there is also an Unexpose() function to unexpose a channel. If\nmultiple channels are exposed under the same ID which channel(s)\nreceive a message depends on the ID. ID's that start with a '+'\ncharacter are considered \"broadcast\" ID's and messages sent to them are\ndelivered to all channels exposed under that ID. All other ID's are\nconsidered \"unicast\" and messages sent to them are delivered to a single\nchannel exposed under that ID (determined using a pseudo-random\nalgorithm).\n\nTo receive exposer errors one can expose error channels (of type chan\nerror) under the special broadcast ID \"+err/\". All such error channels\nwill receive transport errors, etc. [The special broadcast ID \"+err/\" is\nlocal to the running process and cannot be remoted.]\n\n## Binding a channel\n\nIn order to bind a channel to an \"address\" the Bind() function must be\nused; to unbind the channel simply close the channel.\nAddresses in this package depend on the underlying transport and take\nthe form of URI's. For the default TCP transport an address has the\nsyntax: tcp://HOST[:PORT]/ID\n\nWhen using Bind() an error channel (of type chan error) may also be\nspecified. This error channel will receive transport errors, etc.\nrelated to the bound channel.\n\n## Marshaling\n\nThis package encodes/decodes messages using one of the following\nbuiltin encoding formats. These builtin formats can also be used to\nencode channels into references that can later be decoded and\nreconstructed on a different machine.\n\n- netgob: extension of the standard gob format that also allows for\nchannels to be encoded/decoded (https://github.com/billziss-gh/netgob)\n- netjson: extension of the standard json format that also allows for\nchannels to be encoded/decoded (https://github.com/billziss-gh/netjson)\n\nChannels that are marshaled in this way are also implicitly exposed\nand bound. When a message that is being sent contains a channel, a\nreference is computed for that channel and the channel is implicitly\nexposed under that reference. When the message arrives at the target\nmachine the reference gets decoded and a new channel is constructed and\nimplicitly bound back to the marshaled channel.\n\nIt is now possible to use the implicitly bound channel to send\nmessages back to the marshaled and implicitly exposed channel.\nImplicitly exposed channels that are no longer in use will be\neventually garbage collected. Implicitly bound channels must be\nclosed when they will no longer be used for communication.\n\n## Transports\n\nThis package comes with a number of builtin transports:\n\n- tcp: plain TCP transport\n- tls: secure TLS (SSL) transport\n- http: sockets over HTTP (similar to net/rpc protocol)\n- https: sockets over HTTPS (similar to net/rpc protocol)\n- ws: (optional) WebSocket transport\n- wss: (optional) secure WebSocket transport\n\nIt is possible to add transports by implementing the Transport and\nLink interfaces.\n\n## Example\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/billziss-gh/netchan/netchan\"\n)\n\nfunc ping(wg *sync.WaitGroup, count int) {\n\tdefer wg.Done()\n\n\tpingch := make(chan chan struct{})\n\terrch := make(chan error, 1)\n\terr := netchan.Bind(\"tcp://127.0.0.1/pingpong\", pingch, errch)\n\tif nil != err {\n\t\tpanic(err)\n\t}\n\n\tfor i := 0; count \u003e i; i++ {\n\t\t// send a new pong (response) channel\n\t\tpongch := make(chan struct{})\n\t\tpingch \u003c- pongch\n\n\t\tfmt.Println(\"ping\")\n\n\t\t// wait for pong response, error or timeout\n\t\tselect {\n\t\tcase \u003c-pongch:\n\t\tcase err = \u003c-errch:\n\t\t\tpanic(err)\n\t\tcase \u003c-time.After(10 * time.Second):\n\t\t\terr = errors.New(\"timeout\")\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\tpingch \u003c- nil\n\n\tclose(pingch)\n}\n\nfunc pong(wg *sync.WaitGroup, exposed chan struct{}) {\n\tdefer wg.Done()\n\n\tpingch := make(chan chan struct{})\n\terr := netchan.Expose(\"pingpong\", pingch)\n\tif nil != err {\n\t\tpanic(err)\n\t}\n\n\tclose(exposed)\n\n\tfor {\n\t\t// receive the pong (response) channel\n\t\tpongch := \u003c-pingch\n\t\tif nil == pongch {\n\t\t\tfmt.Println(\"END\")\n\t\t\tbreak\n\t\t}\n\n\t\tfmt.Println(\"pong\")\n\n\t\t// send the pong response\n\t\tpongch \u003c- struct{}{}\n\t}\n\n\tnetchan.Unexpose(\"pingpong\", pingch)\n}\n\nfunc main() {\n\twg := \u0026sync.WaitGroup{}\n\n\texposed := make(chan struct{})\n\twg.Add(1)\n\tgo pong(wg, exposed)\n\t\u003c-exposed\n\n\twg.Add(1)\n\tgo ping(wg, 10)\n\n\twg.Wait()\n\n\t// Output:\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// ping\n\t// pong\n\t// END\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbillziss-gh%2Fnetchan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbillziss-gh%2Fnetchan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbillziss-gh%2Fnetchan/lists"}