{"id":28194309,"url":"https://github.com/monkey-projects/socket-async","last_synced_at":"2025-08-31T15:04:48.171Z","repository":{"id":194955344,"uuid":"691943597","full_name":"monkey-projects/socket-async","owner":"monkey-projects","description":"Clojure lib that links Java SocketChannels to core.async channels","archived":false,"fork":false,"pushed_at":"2023-09-15T08:46:58.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2023-09-15T23:44:51.644Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","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/monkey-projects.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}},"created_at":"2023-09-15T08:11:57.000Z","updated_at":"2023-09-15T23:45:02.981Z","dependencies_parsed_at":null,"dependency_job_id":"a1376142-d96f-4053-b104-ac7671386739","html_url":"https://github.com/monkey-projects/socket-async","commit_stats":null,"previous_names":["monkey-projects/socket-async"],"tags_count":1,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fsocket-async","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fsocket-async/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fsocket-async/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monkey-projects%2Fsocket-async/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monkey-projects","download_url":"https://codeload.github.com/monkey-projects/socket-async/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254535798,"owners_count":22087399,"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":[],"created_at":"2025-05-16T13:11:52.174Z","updated_at":"2025-05-16T13:12:07.451Z","avatar_url":"https://github.com/monkey-projects.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Socket Async\n\nThis is a small Clojure lib that provides functionality to links\n[Java SocketChannels](https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/nio/channels/SocketChannel.html) to Clojure's [core.async channels](https://clojure.github.io/core.async/).\n\n## Why?\n\nAlthough it seems like something fairly straightforward and basic, I could not find\nanything like it.  I just needed something that allows you to write Clojure structures\nthat can be serialized (into `edn` for example) to a channel, and then can be read\nback on the other end.  With plain `core.async` channels this is easy.  But for some\nIPC purposes, it's handy to stream this over a socket channel (like a Unix domain\nsocket, aka UDS).\n\nIt's more complicated than it seems, especially since Java does not provide an\nout-of-the-box way to read from a socket channel to an `InputStream`, unless you're\nusing network channels.  So it was not possible with UDS.\n\n## Usage\n\nInclude it in your project:\n```clojure\n# deps.edn\n{:deps {com.monkeyprojects/socket-async {:mvn/version \"..latest..\"}}}\n\n# Or project.clj\n[com.monkeyprojects/socket-asybnc \"..latest\"]\n```\n\nThe core functionality is in `monkey.socket-async.core`.  There are also some\nhelper functions for UDS in `monkey.socket-async.uds`, but you could also directly\nuse the [Java classes](https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/nio/channels/package-summary.html).  You also need `core.async` channels, of course.  The two \"work horses\"\nare `read-onto-channel` and `write-from-channel`.  The former reads `EDN` from a\n`SocketChannel` and puts the decoded objects onto a channel.  The latter does the\nopposite, it reads objects from a channel, encodes them as `EDN` and writes that\nstring to the socket channel.  For example:\n\n```clojure\n(require '[monkey.socket-async.core :as c])\n(require '[monkey.socket-async.uds :as uds])\n\n;; Set up socket connection\n(def path \"test.sock\")\n(def addr (uds/make-address path))\n(def listener (uds/listen-socket addr)) ; Start listening\n(def client (uds/connect-socket addr))  ; Connect to the server\n(def server (uds/accept listener) ; Accept incoming connection\n\n;; At this point you have to socket channels, client and server\n;; that are connected to each other.\n\n(require '[clojure.core.async :as ca :refer [go \u003e!]])\n\n(def in (ca/chan))\n(def out (ca/chan))\n\n;; Connect the channels to the sockets, in one direction in this example\n(c/read-onto-channel server in)\n(c/write-from-channel out client)\n\n;; Send something\n(go (\u003e! out {:message \"Hi, this is a test\"}))\n\n;; Receive it.  Set a timeout for safety.\n(ca/alts!! [in (ca/timeout 1000)])\n;; This should return the message we just wrote\n```\n\nThe `read-onto-channel` function also accepts an additional exception handler fn,\nthat gets called when an IO exception occurs.  This typically means the connection\nwas closed.  The handler should return `false` if we should not continue processing\nfurther messages.  This is the default behaviour.  But you could provide your own,\nfor example to do error reporting or logging, or handle certain edge cases.\n\n## TODO\n\nCurrently this only supports `EDN`, but it could be expanded so that you can configure\nthe serialization method (e.g. use `JSON` instead).\n\n## License\n\nCopyright (c) 2023 by Monkey Projects\n[MIT license](LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonkey-projects%2Fsocket-async","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonkey-projects%2Fsocket-async","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonkey-projects%2Fsocket-async/lists"}