{"id":38054193,"url":"https://github.com/40ants/reblocks-websocket","last_synced_at":"2026-01-16T20:21:48.889Z","repository":{"id":143092995,"uuid":"568161634","full_name":"40ants/reblocks-websocket","owner":"40ants","description":"Websocket support for Reblocks framework","archived":false,"fork":false,"pushed_at":"2025-06-14T21:58:40.000Z","size":155,"stargazers_count":5,"open_issues_count":3,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-14T22:41:39.351Z","etag":null,"topics":["common-lisp","reblocks","webframework","websocket"],"latest_commit_sha":null,"homepage":"https://40ants.com/reblocks-websocket/","language":"Common Lisp","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/40ants.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2022-11-19T16:37:26.000Z","updated_at":"2025-06-14T21:58:43.000Z","dependencies_parsed_at":"2025-02-25T11:23:27.677Z","dependency_job_id":null,"html_url":"https://github.com/40ants/reblocks-websocket","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/40ants/reblocks-websocket","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Freblocks-websocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Freblocks-websocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Freblocks-websocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Freblocks-websocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/40ants","download_url":"https://codeload.github.com/40ants/reblocks-websocket/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/40ants%2Freblocks-websocket/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28482267,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"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":["common-lisp","reblocks","webframework","websocket"],"created_at":"2026-01-16T20:21:40.782Z","updated_at":"2026-01-16T20:21:48.875Z","avatar_url":"https://github.com/40ants.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-40README-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n# reblocks-websocket - Reblocks extension adding a bidirectional communication via Websocket.\n\n\u003ca id=\"reblocks-websocket-asdf-system-details\"\u003e\u003c/a\u003e\n\n## REBLOCKS-WEBSOCKET ASDF System Details\n\n* Description: Reblocks extension allowing to add a bidirectional communication via Websocket between a backend and Reblocks widgets.\n* Licence: Unlicense\n* Author: Alexander Artemenko \u003csvetlyak.40wt@gmail.com\u003e\n* Homepage: [https://40ants.com/reblocks-websocket/][6f15]\n* Bug tracker: [https://github.com/40ants/reblocks-websocket/issues][e6f2]\n* Source control: [GIT][b1a1]\n* Depends on: [alexandria][8236], [bordeaux-threads][3dbf], [jonathan][6dd8], [log4cl-extras][691c], [parenscript][7921], [reblocks][184b], [reblocks-parenscript][c07c], [serapeum][c41d], [websocket-driver][4f50]\n\n[![](https://github-actions.40ants.com/40ants/reblocks-websocket/matrix.svg?only=ci.run-tests)][0497]\n\n![](http://quickdocs.org/badge/reblocks-websocket.svg)\n\nThis module allows you to push some information from backend to frontend\nand. In this case, updates of widgets's state on the client are\ninitiated by server. For example, you can have some sort of long running\nprocess on the server and need to show it's status to the user.\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-40INSTALLATION-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n## Installation\n\nThis library depends on Reblocks (Weblocks fork) and a websocket-driver.\nIf you will use Woo server then probably you'll need this fork of the websocket-driver\n([make-woo-work-from-separate-threads][ef5d] branch).\nHowever, may be the recent version of websocket-driver will work just find, I don't know.\n\nYou can install this library from Quicklisp, but you want to receive updates quickly, then install it from Ultralisp.org:\n\n```\n(ql-dist:install-dist \"http://dist.ultralisp.org/\"\n                      :prompt nil)\n(ql:quickload :reblocks-websocket)\n```\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-40USAGE-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n## Usage\n\nDefine you widget and inherit it from the\n[`reblocks-websocket:websocket-widget`][c36a]:\n\n```lisp\n(reblocks:defwidget counter-box (reblocks-websocket:websocket-widget)\n  ((counter :initform 0\n            :accessor counter)))\n```\nDefine a code which will start some sort of background activity. In this\nexample we are doing it right when widget was created in the beginning\nof the user session, but of cause, you can do it as a reaction on an\naction.\n\n```lisp\n(defmethod initialize-instance ((instance counter-box) \u0026rest restargs)\n  (declare (ignorable restargs))\n  (call-next-method)\n\n  (reblocks-websocket:in-thread (\"Update counter\")\n    (sleep 3)\n    ;; Updating counter\n    (incf (counter instance))\n    (reblocks:update instance)))\n```\nThat is it. Define a render method as usual and use the widget on the\npage. Counter will be updated automatically. This works like a magic,\na framework makes all dirty work under the hood.\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-40API-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n## API\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-40REBLOCKS-WEBSOCKET-3FPACKAGE-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n### REBLOCKS-WEBSOCKET\n\n\u003ca id=\"x-28-23A-28-2818-29-20BASE-CHAR-20-2E-20-22REBLOCKS-WEBSOCKET-22-29-20PACKAGE-29\"\u003e\u003c/a\u003e\n\n#### [package](26e8) `reblocks-websocket`\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-7C-40REBLOCKS-WEBSOCKET-3FClasses-SECTION-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n#### Classes\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-40REBLOCKS-WEBSOCKET-24NO-ACTIVE-WEBSOCKETS-3FCLASS-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n##### NO-ACTIVE-WEBSOCKETS\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-3ANO-ACTIVE-WEBSOCKETS-20CONDITION-29\"\u003e\u003c/a\u003e\n\n###### [condition](5a04) `reblocks-websocket:no-active-websockets` (error)\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-40REBLOCKS-WEBSOCKET-24WEBSOCKET-WIDGET-3FCLASS-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n##### WEBSOCKET-WIDGET\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-3AWEBSOCKET-WIDGET-20CLASS-29\"\u003e\u003c/a\u003e\n\n###### [class](a3c9) `reblocks-websocket:websocket-widget` (widget)\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-7C-40REBLOCKS-WEBSOCKET-3FFunctions-SECTION-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n#### Functions\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-3ASEND-COMMAND-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n##### [function](b8ed) `reblocks-websocket:send-command` method-name \u0026rest args\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-3ASEND-SCRIPT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n##### [function](f9a4) `reblocks-websocket:send-script` script\n\nSends `JS` script to frontend via Websocket.\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-7C-40REBLOCKS-WEBSOCKET-3FMacros-SECTION-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n#### Macros\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-3AIN-THREAD-20-2840ANTS-DOC-2FLOCATIVES-3AMACRO-29-29\"\u003e\u003c/a\u003e\n\n##### [macro](bc0e) `reblocks-websocket:in-thread` (thread-name) \u0026body body\n\nStarts given piece of code in named thread, ensiring that reblocks/session::*session* and\nreblocks/request:*request* will be bound during it's execution.\n\nAlso, it set reblocks.websocket:*backround* to true, to make `update' method distinguish\nbetween usual request processing and background activity.\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-DOCS-2FINDEX-3A-3A-7C-40REBLOCKS-WEBSOCKET-3FVariables-SECTION-7C-2040ANTS-DOC-2FLOCATIVES-3ASECTION-29\"\u003e\u003c/a\u003e\n\n#### Variables\n\n\u003ca id=\"x-28REBLOCKS-WEBSOCKET-3A-2ABACKGROUND-2A-20-28VARIABLE-29-29\"\u003e\u003c/a\u003e\n\n##### [variable](2ac2) `reblocks-websocket:*background*` nil\n\nThis variable becomes t during background processing.\n\n\n[6f15]: https://40ants.com/reblocks-websocket/\n[c36a]: https://40ants.com/reblocks-websocket/#x-28REBLOCKS-WEBSOCKET-3AWEBSOCKET-WIDGET-20CLASS-29\n[b1a1]: https://github.com/40ants/reblocks-websocket\n[0497]: https://github.com/40ants/reblocks-websocket/actions\n[26e8]: https://github.com/40ants/reblocks-websocket/blob/bde773ad242d5e131780245efa480ec1a5425a6e/src/websocket.lisp#L1\n[a3c9]: https://github.com/40ants/reblocks-websocket/blob/bde773ad242d5e131780245efa480ec1a5425a6e/src/websocket.lisp#L227\n[2ac2]: https://github.com/40ants/reblocks-websocket/blob/bde773ad242d5e131780245efa480ec1a5425a6e/src/websocket.lisp#L388\n[5a04]: https://github.com/40ants/reblocks-websocket/blob/bde773ad242d5e131780245efa480ec1a5425a6e/src/websocket.lisp#L392\n[f9a4]: https://github.com/40ants/reblocks-websocket/blob/bde773ad242d5e131780245efa480ec1a5425a6e/src/websocket.lisp#L427\n[b8ed]: https://github.com/40ants/reblocks-websocket/blob/bde773ad242d5e131780245efa480ec1a5425a6e/src/websocket.lisp#L447\n[bc0e]: https://github.com/40ants/reblocks-websocket/blob/bde773ad242d5e131780245efa480ec1a5425a6e/src/websocket.lisp#L525\n[e6f2]: https://github.com/40ants/reblocks-websocket/issues\n[ef5d]: https://github.com/svetlyak40wt/websocket-driver/tree/make-woo-work-from-separate-threads\n[8236]: https://quickdocs.org/alexandria\n[3dbf]: https://quickdocs.org/bordeaux-threads\n[6dd8]: https://quickdocs.org/jonathan\n[691c]: https://quickdocs.org/log4cl-extras\n[7921]: https://quickdocs.org/parenscript\n[184b]: https://quickdocs.org/reblocks\n[c07c]: https://quickdocs.org/reblocks-parenscript\n[c41d]: https://quickdocs.org/serapeum\n[4f50]: https://quickdocs.org/websocket-driver\n\n* * *\n###### [generated by [40ANTS-DOC](https://40ants.com/doc/)]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F40ants%2Freblocks-websocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F40ants%2Freblocks-websocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F40ants%2Freblocks-websocket/lists"}