{"id":24290528,"url":"https://github.com/dstreet/microserv","last_synced_at":"2025-10-30T10:36:24.135Z","repository":{"id":50944063,"uuid":"87646721","full_name":"dstreet/microserv","owner":"dstreet","description":"JSON-RPC over websocket with multicast service discovery","archived":false,"fork":false,"pushed_at":"2024-06-21T06:09:49.000Z","size":345,"stargazers_count":6,"open_issues_count":5,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-06T13:06:53.225Z","etag":null,"topics":["distributed-systems","experimental","json-rpc","microservices","multicast","soa","websockets"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/dstreet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2017-04-08T16:12:10.000Z","updated_at":"2022-04-12T17:59:58.000Z","dependencies_parsed_at":"2024-02-15T05:27:50.058Z","dependency_job_id":"af0b24cd-db95-45a6-87be-1782a5113d99","html_url":"https://github.com/dstreet/microserv","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dstreet%2Fmicroserv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dstreet%2Fmicroserv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dstreet%2Fmicroserv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dstreet%2Fmicroserv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dstreet","download_url":"https://codeload.github.com/dstreet/microserv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234195778,"owners_count":18794356,"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":["distributed-systems","experimental","json-rpc","microservices","multicast","soa","websockets"],"created_at":"2025-01-16T11:53:09.078Z","updated_at":"2025-09-25T13:31:19.737Z","avatar_url":"https://github.com/dstreet.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Microserv\n![Travis CI](https://travis-ci.org/dstreet/microserv.svg?branch=master)\n[![Known Vulnerabilities](https://snyk.io/test/github/dstreet/microserv/badge.svg)](https://snyk.io/test/github/dstreet/microserv)\n[![npm](https://img.shields.io/npm/v/microserv.svg)]()\n\nJSON-RPC over websocket with multicast service discovery with a browser compatible client\n\n## Installation\n```\nnpm install --save microserv\n```\n\n## Usage\n\n### Service A\n```javascript\nconst { Server, Service } = require('microserv')\n\nconst server = new Server('my-app', { port: 3000 })\nconst msgService = new Service('message')\n\nmsgService.register('getMessage', () =\u003e {\n\treturn 'Hello, world!'\n})\n\nserver.addService(msgService)\nserver.listen()\nserver.announce()\n```\n\n### Service B\n```javascript\nconst http = require('http')\nconst { Server, Service } = require('microserv')\n\nconst server = new Server('my-app', { port: 3001 })\nconst mathService = new Service('math')\n\nmathService.register('add', (a, b) =\u003e {\n\treturn a + b\n})\n\nserver.addService(mathService)\n\n// Wait for the message service to be ready\nserver.need('message')\n\t.then(([ message ]) =\u003e {\n\t\tconst app = http.createServer((req, res) =\u003e {\n\t\t\tres.statusCode = 200\n\t\t\tres.setHeader('Content-Type', 'text/plain')\n\n\t\t\t// Call the message service `getMessage` method\n\t\t\tmessage.getMessage()\n\t\t\t\t.then(msg =\u003e {\n\t\t\t\t\tres.end(msg)\n\t\t\t\t\t// { type: 'string', data: 'Hello, world!' }\n\t\t\t\t})\n\t\t})\n\n\t\tapp.listen(8080, '127.0.0.1')\n\t})\n\nserver.listen()\nserver.announce()\n```\n\n### Client\n```javascript\nconst { Client } = require('microserv')\n\nconst client = new Client()\n\nclient.need('message', 'math')\n\t.then(([ message, math ]) =\u003e {\n\t\tmessage\n\t\t\t.getMessage()\n\t\t\t.then(msg =\u003e console.log(msg))\n\n\t\tmath\n\t\t\t.add(1, 2)\n\t\t\t.then(sum =\u003e console.log(sum))\n\t})\n\nclient.connect('ws://localhost:3000')\nclient.connect('ws://localhost:3001')\n```\n\n## Server\n\n```javascript\nconst server = new Server('my-app', { port: 3001 })\n```\n\n### new Server(namespace[,options]) -\u003e Client\n\nInstantiate a client\n\nParameters:\n* `address` {String}: The service namespace. Only services in the same namespace can connect to each other.\n* `options` {Object}: Websocket options\n\t* `port` {Number}: Websocket port\n\t* `interval` {Number}: How often to announce the service (in ms). Defaults to `5000`.\n\t* `sever` {http.Server|https.server}: A server to use as the websocket server. If set, will override `port`.\n\t* `secure` {Boolean}: Use secure websockets. Defaults to `false`.\n\t* `serviceTransform` {Function}: A function to transform the data returned from an rpc call. Defaults to noop.\n\t* `authorization` {Any}: Credentials to pass to Server when connecting\n\t* `authorizeClient` {Function}: A sync or async function to authorize a Client. Function is passed the Client's `authorization` credentials\n\t* `dns` {Object}: [dns-discovery](https://github.com/mafintosh/dns-discovery) options\n\n### server.addService(service) -\u003e Server\n\nAdd a service to the server, and announce the service to connected peers\n\nParameters:\n* `service` {Service}: A Service instance\n\n### server.need(...services) -\u003e Promise\n\nList required services. Resolves with each of the required services of type ClientService\n\nParameters:\n* `services` {String}: Service names\n\n### server.listen() -\u003e Server\n\nBegin listening for peers\n\n### server.announce() -\u003e Server\n\nAnnounce the service on the network. Will reannounce the service at the interval provided via `opts`.\n\n### Event: 'error'\n\nEmitted when there is an error on the server\n\n### Event: 'connection_reset'\n\nEmitted when a connected socket is reset\n\n## Service\n\n```javascript\nconst service = new Service('my-service')\n```\n\n### new Service(name) -\u003e Service\n\nInstantiate a new Service\n\nParameters:\n* `name` {String}: The service name that will be announced to peers\n\n### service.register(method, cb[, resultType]) -\u003e Service\n\nRegister an rpc method with the service\n\nParameters:\n* `method` {String}: The name of the method\n* `cb` {Function}: The function to invoke when the rpc method is called\n* `resultType` {String}: The type of data returned by the method. Defaults to `typeof result`\n\n### service.emit(name, data)\n\nEmits an event via the websocket\n\nParameters:\n* `name` {String}: The event name\n* `data` {*}: The event data\n\n\n## ClientService\n\nReturned from `server.need()`. This should not be instantiated direclty.\n\n### clientService.subscribe(name, cb)\n\nSubscribe to a service event\n\nParameters:\n* `name` {String}: The name of the event\n* `cb` {Function}: The event callback\n\n### clientService.service_method(*) -\u003e Object\n\nEach method registered with the service is exposed a method of the client service. Returns and object with `data` and `type` properties.\n\n### Event: 'close'\n\nEmitted when the connection to the service is lost\n\n### Event: 'reopen'\n\nEmitted when the connection to a lost service is reestablished\n\n\n## Client\n\n```javascript\nconst client = new Client()\n```\n\n### new Client([opts, rpcOpts]) -\u003e Client\n\nInstantiate a new Client\n\nParameters:\n* `opts` {Object}: Options\n\t* `serviceTransform` {Function}: A function to transform the data returned from an rpc call. Defaults to noop.\n\t* `authorization` {Any}: Credentials to pass to Server when connecting\n* `rpcOpts` {Object}: Options for [rpc-websockets](https://github.com/qaap/rpc-websockets)\n\n### client.connect(connection) -\u003e Websocket\n\nConnect to a specific websocket server\n\nParameters:\n* `connection` {String}: The server connection string (eg. ws://localhost:3001)\n\n### client.need(...service) -\u003e Promise\n\nList required services. Resolves with each of the required services of type ClientService\n\nParameters:\n* `services` {String}: Service names\n\n### Event: 'close'\n\nEmitted when the connection to a service is closed\n\n### Event: 'error'\n\n### Event: 'unauthorized'\n\nEmitted when the client fails authorization\n\n\n## Tests\n\n```\nnpm run test\n```\n\n## License\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdstreet%2Fmicroserv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdstreet%2Fmicroserv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdstreet%2Fmicroserv/lists"}