{"id":13411317,"url":"https://github.com/jkyberneees/distributed-eventemitter","last_synced_at":"2025-03-23T12:34:02.626Z","repository":{"id":57213063,"uuid":"54847631","full_name":"jkyberneees/distributed-eventemitter","owner":"jkyberneees","description":"The ultra fast, distributed (multi process and multi server), STOMP based event emitter for Node.js!","archived":false,"fork":false,"pushed_at":"2016-10-31T08:51:52.000Z","size":36,"stargazers_count":25,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-12T13:38:18.603Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jkyberneees.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}},"created_at":"2016-03-27T20:53:24.000Z","updated_at":"2023-05-31T21:06:57.000Z","dependencies_parsed_at":"2022-08-24T21:41:50.377Z","dependency_job_id":null,"html_url":"https://github.com/jkyberneees/distributed-eventemitter","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/jkyberneees%2Fdistributed-eventemitter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkyberneees%2Fdistributed-eventemitter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkyberneees%2Fdistributed-eventemitter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jkyberneees%2Fdistributed-eventemitter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jkyberneees","download_url":"https://codeload.github.com/jkyberneees/distributed-eventemitter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221851053,"owners_count":16891706,"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":"2024-07-30T20:01:12.887Z","updated_at":"2024-10-28T15:51:13.805Z","avatar_url":"https://github.com/jkyberneees.png","language":"JavaScript","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=6LVSDLF7D863G"],"categories":["Web Development"],"sub_categories":["Javascript"],"readme":"\n# Why?\n  The library solve the need of a multi process and multi server oriented messaging API in Node.js.\n  \u003cbr\u003e Using the known [EventEmitter](https://nodejs.org/api/events.html/) API, listeners registration and events emitting is super simple.\n  \u003cbr\u003e A new 'emitToOne' method allows one-to-one events notification, intended for request/response flows on clustered services. \n  \u003cbr\u003e The classic 'emit' method broadcast custom events to local and distributed listeners.\n  \n  For non-distributed usage of this API (browser, single node process or development) developers can use: [process-eventemitter](https://github.com/jkyberneees/process-eventemitter)\n\n  \u003e Donate to support the evolution of this project:  \n  [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=6LVSDLF7D863G)\n\n# Quick Start\n1. Mailer server (A.js):\n\n  ```js\n  var EventEmitter = require('distributed-eventemitter');\n  var events = new EventEmitter(); // host: localhost, port: 61613\n  events.connect().then(() =\u003e {\n    events.on('email.send', (message, resolve, reject) =\u003e {\n      console.log('sending email...');\n      //... send email\n      // ...\n\n      resolve('sent');\n    });\n  });\n  ```\n\n2. Run mailer server as a cluster with [PM2](https://www.npmjs.com/package/pm2):\n\n  ```bash\n  pm2 start A.js -i 4 --node-args=\"--harmony\"\n  ```\n\n3. Mailer client  (B.js):\n\n  ```js\n  var EventEmitter = require('distributed-eventemitter');\n  var events = new EventEmitter(); // host: localhost, port: 61613\n  events.connect().then(() =\u003e {\n    events.emitToOne('email.send', {\n      to: 'kyberneees@gmail.com',\n      subject: 'Hello Node.js',\n      body: 'Introducing easy distributed messaging for Node.js...'\n    }, 3000).then((response) =\u003e {\n      if ('sent' === response) {\n        console.log('email was sent!');\n      }\n    }).catch(console.log.bind());\n  });\n  ```\n4. Run mailer client:\n\n  ```bash\n  node --harmony B.js\n  ```\n\n## Example using ES6 generators\n```js \n\"use strict\";\n\nconst EventEmitter = require('distributed-eventemitter');\nconst co = require('co');\nconst events = new EventEmitter(); // host: localhost, port: 61613\n\nco(function* () {\n    try {\n        yield events.connect();\n        let response = yield events.emitToOne('email.send', {\n            to: 'kyberneees@gmail.com',\n            subject: 'Hello Node.js',\n            body: 'Introducing easy distributed messaging for Node.js...'\n        }, 3000);\n\n        if ('sent' === response) {\n            console.log('email was sent!');\n        }\n        yield events.disconnect();\n    } catch (error) {\n        console.log('error: ' + error);\n    }\n});\n```\n\n# Requirements\n- Running [STOMP compliant server](http://activemq.apache.org/installation.html) instance. Default client destinations are:\n  1. _/topic/distributed-eventemitter_: Used for events broadcast (emit)\n  - _/queue/distributed-eventemitter_: Used for one-to-one events (emitToOne)\n\n    \u003e If the server require clients to be authenticated, you can use:\n\n  ```js\n  {\n    'host': 'localhost',\n    'connectHeaders': {\n      'heart-beat': '5000,5000',\n      'host': '',\n      'login': 'username',\n      'passcode': 'password'\n    }\n  }\n  ```\n\n# Installation\n\n```bash\n$ npm install distributed-eventemitter\n```\n\n# Features\n- Extends [eventemitter2](https://www.npmjs.com/package/eventemitter2/). ([wildcards](https://www.npmjs.com/package/eventemitter2/#api) are enabled). \n- ECMA6 Promise based API.\n- Request/Response communication intended for service clusters (emitToOne). Uncaught exceptions automatically invoke 'reject(error.message)'  \n- Events broadcast to local and distributed listeners (emit)\n- Works with any STOMP compliant server (ie. ActiveMQ, RabbitMQ,  ...).\n- Uses [stompit](https://www.npmjs.com/package/stompit/) as STOMP client. (automated server reconnection is supported)\n\n# Config params\n```js\nvar config = {};\nconfig.destination = 'distributed-eventemitter'; // server topic and queue destinations\nconfig.excludedEvents = []; // events that are not distributed\nconfig.servers = [{\n  'host': 'localhost',\n  'port': 61613,\n  'connectHeaders': {\n    'heart-beat': '5000,5000',\n    'host': '',\n    'login': '',\n    'passcode': ''\n  }\n}];\nconfig.reconnectOpts = {\n  maxReconnects: 10;\n}\n\nvar events = new EventEmitter(config);\n```\n  For more details about 'servers' and 'reconnectOpts' params please check: http://gdaws.github.io/node-stomp/api/connect-failover/ \n\n# Internal events\n```js\nevents.on('connected', (emitterId) =\u003e {\n    // triggered when the emitter has been connected to the network (STOMP server)\n});\n\nevents.on('disconnected', (emitterId) =\u003e {\n    // triggered when the emitter has been disconnected from the network (STOMP server)\n});\n\nevents.on('error', (error) =\u003e {\n   // triggered when an error occurs in the connection channel. \n}):\n\nevents.on('connecting', (connector) =\u003e {\n   // triggered when the STOMP client is trying to connect to a server.\n}):\n\nevents.on('request', (event, request, raw) =\u003e {\n   // triggered before invoke a listener using emitToOne feature\n   \n   // request data filtering and modification is allowed\n   // example:\n   request.data = ('string' === typeof request.data) ? request.data.toUpperCase() : request.data\n}):\n\nevents.on('response', (event, response, raw) =\u003e {\n   // triggered after invoke a listener using emitToOne feature\n   \n   // response data filtering and modification is allowed\n   // example:\n   if (response.ok)\n     response.data = ('string' === typeof response.data) ? response.data.toUpperCase() : response.data\n   else \n     console.log('error ocurred: ' + response.data.message);\n}):\n\n```\n\n# API\n**getId**: Get the emitter instance unique id.\n\n```js\nevents.getId(); // UUID v4 value\n```\n\n**connect**: Connect the emitter to the server. Emit the 'connected' event.\n\n```js\nevents.connect().then(()=\u003e {\n  console.log('connected');\n});\n```\n\n**disconnect**: Disconnect the emitter from the server. Emit the 'disconnected' event.\n\n```js\nevents.disconnect().then(()=\u003e {\n  console.log('disconnected');\n});\n```\n\n**emitToOne**: Notify a custom event to only one target listener (locally or in the network). The method accept only one argument as event data.\n\n```js\nevents.on('my.event', (data, resolve, reject) =\u003e {\n  if ('hello' === data){\n    resolve('world');\n  } else {\n    reject('invalid args');\n  }\n});\n\n// calling without timeout\nevents.emitToOne('my.event', 'hello').then((response) =\u003e {\n  console.log('world' === response);\n});\n\n// calling with timeout (ms)\nevents.emitToOne('my.event', {data: 'hello'}, 100).catch((error) =\u003e {\n  console.log('invalid args' === error);\n});\n```\n# Roadmap\n\n1. Express integration.\n\n# Known limitations\n  - The feature 'emitAsync' from the EventEmitter2, only work locally(not distributed).\n\n# Tests\n\n```bash\n$ npm install\n$ npm test\n```\n# History changes\n\n## 1.1.x\n  - From version 1.1.0+ we use Stompit as STOMP client because Stompjs does not support server reconnections and is also unmaintained.\n  - No API changes from 1.0 version except the configuration params, since now we consider a list of STOMP servers to connect/reconnect.\n\n## 1.1.1\n  - Supporting request/request events intended for pre invocation content filtering and modification.\n\n## 1.1.2\n  - Fixing dependencies declaration (due to automatic modification from 'npm update --save').\n  \n## 1.1.3\n  - Fixing issue on distributed events broadcast(emit) that caused repeated broadcasts.\n  \n## 1.1.4\n  - Updating dependencies and adding generators example to docs. \n  \n## 1.1.5\n  - Updating dependencies and docs. \n\n## 1.1.6 \n  - Improving unexpected error handling when data can't be transmited because the STOMP connection is closed. \n  Produced exceptions are notified as an 'error' event on the emitter.\n  \n## 1.2.0\n  - Supporting [jWebSocket EventBus](http://jwebsocket.org/documentation/reference-guide/event-bus). \n  JVM based applications using the jWebSocket EventBus component, can communicate with nodejs services through this module.\n\n## 1.2.1\n  - Minor source code refactorization. \n  - Package updates.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjkyberneees%2Fdistributed-eventemitter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjkyberneees%2Fdistributed-eventemitter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjkyberneees%2Fdistributed-eventemitter/lists"}