{"id":26505523,"url":"https://github.com/objtalk/objtalk","last_synced_at":"2026-05-15T23:39:35.544Z","repository":{"id":57647870,"uuid":"373231188","full_name":"objtalk/objtalk","owner":"objtalk","description":"a lightweight realtime database for IoT projects","archived":false,"fork":false,"pushed_at":"2023-03-19T16:10:07.000Z","size":204,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-06T01:55:29.770Z","etag":null,"topics":["broker","database","iot","messaging","realtime","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/objtalk.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-02T16:15:01.000Z","updated_at":"2022-11-20T22:48:30.000Z","dependencies_parsed_at":"2025-03-20T21:59:20.239Z","dependency_job_id":null,"html_url":"https://github.com/objtalk/objtalk","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/objtalk/objtalk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objtalk%2Fobjtalk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objtalk%2Fobjtalk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objtalk%2Fobjtalk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objtalk%2Fobjtalk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/objtalk","download_url":"https://codeload.github.com/objtalk/objtalk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/objtalk%2Fobjtalk/sbom","scorecard":{"id":701042,"data":{"date":"2025-08-11","repo":{"name":"github.com/objtalk/objtalk","commit":"1b2b75985ad510c05a2680e7dcb74d5c87fc9c4d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:73: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yaml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yaml:88: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:58: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yaml:65: update your workflow using https://app.stepsecurity.io/secureworkflow/objtalk/objtalk/build.yaml/master?enable=pin","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.3.0 not signed: https://api.github.com/repos/objtalk/objtalk/releases/84025382","Warn: release artifact latest not signed: https://api.github.com/repos/objtalk/objtalk/releases/84025331","Warn: release artifact v0.2.1 not signed: https://api.github.com/repos/objtalk/objtalk/releases/83922207","Warn: release artifact v0.2.0 not signed: https://api.github.com/repos/objtalk/objtalk/releases/83689877","Warn: release artifact v0.1.5 not signed: https://api.github.com/repos/objtalk/objtalk/releases/44167654","Warn: release artifact v0.3.0 does not have provenance: https://api.github.com/repos/objtalk/objtalk/releases/84025382","Warn: release artifact latest does not have provenance: https://api.github.com/repos/objtalk/objtalk/releases/84025331","Warn: release artifact v0.2.1 does not have provenance: https://api.github.com/repos/objtalk/objtalk/releases/83922207","Warn: release artifact v0.2.0 does not have provenance: https://api.github.com/repos/objtalk/objtalk/releases/83689877","Warn: release artifact v0.1.5 does not have provenance: https://api.github.com/repos/objtalk/objtalk/releases/44167654"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/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/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"19 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: RUSTSEC-2021-0145 / GHSA-g98v-hv3f-hcfr","Warn: Project is vulnerable to: RUSTSEC-2024-0375","Warn: Project is vulnerable to: RUSTSEC-2020-0159","Warn: Project is vulnerable to: RUSTSEC-2021-0079 / GHSA-5h46-h7hh-c6x9","Warn: Project is vulnerable to: RUSTSEC-2021-0078 / GHSA-f3pg-qwvg-p99c","Warn: Project is vulnerable to: RUSTSEC-2022-0022 / GHSA-f67m-9j94-qv9j","Warn: Project is vulnerable to: RUSTSEC-2024-0421 / GHSA-h97m-ww89-6jmq","Warn: Project is vulnerable to: RUSTSEC-2022-0090 / GHSA-jw36-hf63-69r9","Warn: Project is vulnerable to: RUSTSEC-2024-0019 / GHSA-r8w9-5wcg-vfj7","Warn: Project is vulnerable to: RUSTSEC-2024-0370","Warn: Project is vulnerable to: RUSTSEC-2022-0013 / GHSA-m5pq-gvj9-9vr8","Warn: Project is vulnerable to: RUSTSEC-2021-0128 / GHSA-4qr3-m7ww-hh9g / GHSA-87xh-9q6h-r5cc / GHSA-92cx-4xm7-jr9m / GHSA-cm8g-544f-p9x9 / GHSA-f6f2-3w33-54r9 / GHSA-g4g4-3pqw-8m7f / GHSA-g87r-23vw-7f87 / GHSA-q89g-4vhh-mvvm","Warn: Project is vulnerable to: RUSTSEC-2020-0071 / GHSA-wcg3-cvx6-7396","Warn: Project is vulnerable to: RUSTSEC-2021-0072 / GHSA-2grh-hm3w-w7hv","Warn: Project is vulnerable to: RUSTSEC-2021-0124 / GHSA-fg7r-2g4j-5cgr","Warn: Project is vulnerable to: RUSTSEC-2023-0005 / GHSA-4q83-7cq4-p6wg","Warn: Project is vulnerable to: GHSA-rr8g-9fpq-6wmg","Warn: Project is vulnerable to: RUSTSEC-2025-0023","Warn: Project is vulnerable to: RUSTSEC-2023-0065 / GHSA-9mcr-873m-xcxp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T05:13:15.271Z","repository_id":57647870,"created_at":"2025-08-22T05:13:15.271Z","updated_at":"2025-08-22T05:13:15.271Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33083812,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T20:25:35.270Z","status":"ssl_error","status_checked_at":"2026-05-15T20:25:34.732Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["broker","database","iot","messaging","realtime","rust"],"created_at":"2025-03-20T21:47:32.038Z","updated_at":"2026-05-15T23:39:35.509Z","avatar_url":"https://github.com/objtalk.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# objtalk\n\n[![Documentation](https://docs.rs/objtalk/badge.svg)](https://docs.rs/objtalk)\n[![Automated Builds](https://github.com/objtalk/objtalk/actions/workflows/build.yaml/badge.svg)](https://github.com/objtalk/objtalk/actions/workflows/build.yaml)\n\nobjtalk is a lightweight realtime database that can be used for IoT projects. It can be used to store and query the state of devices in realtime and also to communicate between devices using events and rpc. Think mqtt but on steroids.\n\nobjtalk stores objects. Each object has a name, a value (json) and a timestamp that indicates when the object was last modified. Objects can be created, modified, removed and queried over an API. Queries can also watch for changes and return them in real time to the client.\n\nThe API can be accessed using multiple transports. The protocol is JSON-RPC-like and can be used over TCP or over a WebSocket. HTTP/REST can also be used for simple commands.\n\nAll objects stored in objtalk can also be viewed in a browser using the builtin admin panel.\n\n## Installation\n\nInstall a [precompiled binary](https://github.com/objtalk/objtalk/releases) or use cargo:\n\n```\n$ cargo install objtalk\n```\n\n## Using the server\n\nCreate a config file, for example called `objtalk.toml`:\n\n```toml\n[storage]\nbackend = \"sqlite\"\nsqlite.filename = \"objtalk.db\"\n\n[[http]]\naddr = \"127.0.0.1:3000\"\nadmin.enabled = true\n#admin.asset-overrides = \"admin\"\n#allow-origin = \"*\"\n\n[[tcp]]\naddr = \"127.0.0.1:3001\"\n```\n\nStart the server:\n\n```sh\n$ objtalk-server --config objtalk.toml\nhttp transport listening on http://127.0.0.1:3000\ntcp transport listening on 127.0.0.1:3001\n```\n\nVisit the admin panel at `http://127.0.0.1:3000`.\n\n## Using the client\n\n```sh\n$ objtalk-cli -u http://127.0.0.1:3000 set foo 42\n$ objtalk-cli -u http://127.0.0.1:3000 get foo\n[\n    {\n        \"name\": \"foo\",\n        \"value\": 42,\n        \"lastModified\": \"2021-05-07T17:53:29.066420Z\"\n    }\n]\n$ objtalk-cli -u http://127.0.0.1:3000 remove foo\n```\n\n## Using objtalk as a rust library\n\nThe objtalk crate provides the `objtalk-server` and `objtalk-cli` binaries, but you can also use it as a library to integrate objtalk into your rust project. Take a look at the [documentation](https://docs.rs/objtalk) for a list of all available methods. You can use the `server` and `client` feature flags to trim down the library.\n\n## Libraries for other languages\n\n- [JavaScript](https://www.npmjs.com/package/objtalk)\n\n## Other integrations\n\n- [Node-RED](https://flows.nodered.org/node/node-red-contrib-objtalk)\n\n## API/Protocol\n\n### Basics\n\n#### set `name` `value`\n\n`set` creates or replaces an object.\n\nusing objtalk-cli:\n\n```\n$ objtalk-cli set sensor '{\"temperature\":20}'\n```\n\nover http:\n\n```\n$ curl -X POST 127.0.0.1:3000/objects/sensor -d '{\"temperature\":20}'\n```\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"set\",\n    \"name\": \"sensor\",\n    \"value\": { \"temperature\": 20 }\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"success\": true\n    }\n}\n```\n\n#### patch `name` `value`\n\n`patch` creates or updates an object. If an object with the same name already exists the value is merged (non-deep).\n\nusing objtalk-cli:\n\n```\n$ objtalk-cli replace sensor '{\"temperature\":20}'\n```\n\nover http:\n\n```\n$ curl -X PATCH 127.0.0.1:3000/objects/sensor -d '{\"temperature\":20}'\n```\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"patch\",\n    \"name\": \"sensor\",\n    \"value\": {\n        \"temperature\": 20\n    }\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"success\": true\n    }\n}\n```\n\n#### get `pattern`\n\n`get` returns all objects where the name matches `pattern`.\n\nObject names look like a file path and consist of multiple parts seperated by forward slashes. Each part can be either a string, a `+` or `*`. `+` matches anything until the next slash, `*` matches anything until the end of the string. Multiple sub-patterns can be combined using a comma and are logically OR-ed togeter.\n\nSome examples:\n- `*` matches all objects\n- `device/lamp/+` matches `device/lamp/livingroom` and `device/lamp/bedroom`, but not `device/sensor/livingroom`\n- `device/+/livingroom` matches `device/lamp/livingroom` and `device/sensor/livingroom`\n- `device/*` matches `device/lamp/livingroom`, `device/lamp/bedroom` and `device/sensor/livingroom`\n- `device/lamp/+,device/sensor/+` matches `device/lamp/livingroom`, `device/lamp/bedroom` and `device/sensor/livingroom`\n\nusing objtalk-cli:\n\n```\n$ objtalk-cli get '*'\n```\n\nover http:\n\n```\n$ curl '127.0.0.1:3000/query?pattern=*'\n```\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"get\",\n    \"pattern\": \"*\"\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"objects\": [\n            {\n                \"name\": \"sensor\",\n                \"value\": { \"temperature\": 20 },\n                \"lastModified\": \"YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ\"\n            }\n        ]\n    }\n}\n```\n\n#### query `pattern`\n\n`query` returns all objects matching `pattern` and watches for changes. The initial response contains all objects that match `pattern`. When new objects with a matching name are created, changed or removed a `queryAdd` event, `queryChange` event or `queryRemove` event is emitted.\n\nusing objtalk-cli: unsupported\n\nover http:\n\n```\n$ curl '127.0.0.1:3000/query?pattern=*' -H \"Accept: text/event-stream\"\n```\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"query\",\n    \"pattern\": \"*\"\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n        \"objects\": [\n            {\n                \"name\": \"sensor\",\n                \"value\": { \"temperature\": 20 },\n                \"lastModified\": \"YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ\"\n            }\n        ]\n    }\n}\n\n{\n    \"type\": \"queryChange\",\n    \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n    \"object\": {\n        \"name\": \"sensor\",\n        \"value\": { \"temperature\": 21 },\n        \"lastModified\": \"YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ\"\n    }\n}\n\n{\n    \"type\": \"queryAdd\",\n    \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n    \"object\": {\n        \"name\": \"foo\",\n        \"value\": { \"bar\": true },\n        \"lastModified\": \"YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ\"\n    }\n}\n\n{\n    \"type\": \"queryChange\",\n    \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n    \"object\": {\n        \"name\": \"foo\",\n        \"value\": { \"bar\": false },\n        \"lastModified\": \"YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ\"\n    }\n}\n\n{\n    \"type\": \"queryRemove\",\n    \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n    \"object\": {\n        \"name\": \"foo\",\n        \"value\": { \"bar\": false },\n        \"lastModified\": \"YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ\"\n    }\n}\n```\n\n#### unsubscribe `queryId`\n\n`unsubscribe` stops watching for changes and removes a query.\n\nusing objtalk-cli: unsupported\n\nover http: implicit when the event-stream is closed\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"unsubscribe\",\n    \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\"\n}\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"success\": true\n    }\n}\n```\n\n#### remove `name`\n\n`remove` removes an object. The return value indicates if an object with the name existed and was successfully removed.\n\nusing objtalk-cli:\n\n```\n$ objtalk-cli remove sensor\n```\n\nover http:\n\n```\n$ curl -X DELETE 127.0.0.1:3000/objects/sensor\n```\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"remove\",\n    \"name\": \"sensor\"\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"existed\": true\n    }\n}\n```\n\n### Events\n\nObjects can also emit events. You can listen for events by creating a query.\n\n#### emit `object` `event` `data`\n\n`emit` publishes an event on an existing object.\n\nusing objtalk-cli: \n\n```\n$ objtalk-cli emit gamepad buttonPress '{\"button\":\"a\"}'\n```\n\nover http:\n\n```\n$ curl -X POST 127.0.0.1:3000/events/gamepad -d '{\"event\":\"buttonPress\",\"data\":{\"button\":\"a\"}}'\n```\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"emit\",\n    \"object\": \"gamepad\",\n    \"event\": \"buttonPress\",\n    \"data\": { \"button\": \"a\" }\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"success\": true\n    }\n}\n```\n\nWhich produces the following event on all queries that match that object:\n\n```json\n{\n    \"type\": \"queryEvent\",\n    \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n    \"object\": \"gamepad\",\n    \"event\": \"buttonPress\",\n    \"data\": { \"button\": \"a\" }\n}\n```\n\n### RPC\n\nMethods can be called on objects. One client is connected to objtalk and listens for method calls, performs them and pushes the result to objtalk. Other clients can call these methods.\n\n#### Calling methods\n\n`invoke` calls a method on an object.\n\nusing objtalk-cli: \n\n```\n$ objtalk-cli invoke device/lamp/livingroom setState '{\"on\":true}'\n```\n\nover http:\n\n```\n$ curl -X POST 127.0.0.1:3000/invoke/device/lamp/livingroom -d '{\"method\":\"setState\",\"args\":{\"on\":true}}'\n```\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"invoke\",\n    \"object\": \"device/lamp/livingroom\",\n    \"method\": \"setState\",\n    \"args\": { \"on\": true }\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"success\": true\n    }\n}\n```\n\n#### Providing method calls\n\nTo provide rpc calls for an object a client (\"provider\") has to connect to objtalk and has to create a query with `provideRpc` set to true. Once another client (\"consumer\") tries to call a method on the object a `queryInvocation` event is emitted on the query. The provider can process the request and return a result to the consumer using the `invokeResult` command.\n\nThe whole flow looks like this:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"query\",\n    \"pattern\": \"device/lamp/livingroom\",\n    \"provideRpc\": true\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n        \"objects\": [\n            {\n                \"name\": \"device/lamp/livingroom\",\n                \"value\": { \"on\": false },\n                \"lastModified\": \"YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ\"\n            }\n        ]\n    }\n}\n\n{\n    \"type\": \"queryInvocation\",\n    \"queryId\": \"01234567-89ab-cdef-0123-456789abcdef\",\n    \"invocationId\": \"fedcba98-7654-3210-fedc-ba9876543210\",\n    \"object\": \"device/lamp/livingroom\",\n    \"method\": \"setState\",\n    \"args\": { \"on\": true }\n}\n\n{\n    \"id\": 2,\n    \"type\": \"invokeResult\",\n    \"invocationId\": \"fedcba98-7654-3210-fedc-ba9876543210\",\n    \"result\": { \"success\": true }\n}\n\n{\n    \"requestId\": 2,\n    \"result\": {\n        \"success\": true\n    }\n}\n```\n\n### Disconnect commands\n\nA client can register a list of commands that are executed once the client disconnects. This can be used, for example, to indicate that a device went offline by changing the value of an object. The supported commands are `set`, `patch`, `remove` and `emit`.\n\n#### setDisconnectCommands `commands`\n\n`setDisconnectCommands` sets the list of commands to execute when the client disconnects.\n\nusing objtalk-cli: unsupported\n\nover http: unsupported\n\nover tcp or websocket:\n\n```json\n{\n    \"id\": 1,\n    \"type\": \"setDisconnectCommands\",\n    \"commands\": [\n        {\n            \"type\": \"set\",\n            \"name\": \"device/foo\",\n            \"value\": { \"offline\": true },\n        },\n        {\n            \"type\": \"patch\",\n            \"name\": \"device/foo\",\n            \"value\": { \"offline\": true },\n        },\n        {\n            \"type\": \"remove\",\n            \"name\": \"client\",\n        },\n        {\n            \"type\": \"emit\",\n            \"name\": \"device/foo\",\n            \"event\": \"offline\",\n            \"data\": {},\n        }\n    ]\n}\n\n{\n    \"requestId\": 1,\n    \"result\": {\n        \"success\": true\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjtalk%2Fobjtalk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobjtalk%2Fobjtalk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobjtalk%2Fobjtalk/lists"}