{"id":19719922,"url":"https://github.com/timboudreau/blurt","last_synced_at":"2026-05-15T06:01:53.455Z","repository":{"id":12067323,"uuid":"14654228","full_name":"timboudreau/blurt","owner":"timboudreau","description":"A little thing for fire-and-forget UDP packets with Java and NodeJS implementations","archived":false,"fork":false,"pushed_at":"2023-07-10T04:11:58.000Z","size":141,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-10T19:42:36.971Z","etag":null,"topics":["cluster","multicast","udp","udp-client","udp-server"],"latest_commit_sha":null,"homepage":null,"language":"Java","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/timboudreau.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2013-11-24T02:06:22.000Z","updated_at":"2022-11-25T16:00:09.000Z","dependencies_parsed_at":"2025-01-10T15:48:56.787Z","dependency_job_id":"f47b83aa-220f-4e44-bac7-773cc67ef5be","html_url":"https://github.com/timboudreau/blurt","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fblurt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fblurt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fblurt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timboudreau%2Fblurt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timboudreau","download_url":"https://codeload.github.com/timboudreau/blurt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241040579,"owners_count":19898896,"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":["cluster","multicast","udp","udp-client","udp-server"],"created_at":"2024-11-11T23:09:43.559Z","updated_at":"2026-05-15T06:01:48.391Z","avatar_url":"https://github.com/timboudreau.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Blurt\n=====\n\nA handy little service for sending off fire-and-forget UDP packets with \nJSON or [BSON](http://bsonspec.org/)\npayloads.  Useful for performance monitoring or as a simple message bus between \napplications or within a cluster.  Each packet contains unique ids to identify the \nhost, application and installed copy of the application, in addition to the payload.\n\nThere are interoperable implementations for Java (using NIO) and \n[NodeJS](http://nodejs.org) in this project.\n\nIt was written with two use-cases in mind: \n\n 1. Providing a low-impact, minimal dependency way for multiple applications \nin a cluster to publish data about what they are doing for monitoring purposes\n 2. Creating a minimally invasive way to integrate unrelated developer tools\nsuch that a dashboard of recent activity can be created, without imposing any\nparticular expectations of what the published data looks like or how (if) it is\nstored.\n\nJava-Blurt\n----------\n\nUses [Giulius](../../../giulius) for configuration and Guice for initialization -\nthis relies on simple properties files or Properties objects bound using Guice.\n\nTo use BSON instead of JSON, do the following in a Guice module:\n\n\t\tbind(BlurtCodec.class).to(BsonCodec.class);\n\nBSON keeps packet size smaller (with IPv4, you want to keep UDP packet size under\n512 bytes).\n\nTo use it, simply ask Guice to inject an instance of ``Blurt``, and then call\nit's ``blurt(Object)`` method.\n\n        @Inject\n        public MyClass(Blurt blurt, SomeObject obj) {\n            blurt.blurt(obj);\n        }\n\nThe object must be serializable using Jackson (if you need to customize serialization,\nsimply bind ``ObjectMapper`` using Guice to a preconfigured one and Blurt will use\nit).\n\nTo receive messages, simply bind ``BlurtReceiver`` - it will be called when there\nis a message:\n\n        public class MyReceiver extends BlurtReceiver {\n            protected void receive(Message\u003cMap\u003cString,Object\u003e\u003e map) {\n                System.out.println(\"Hey, somebody sent me this: \" + map);\n            }\n        }\n\nConfiguration\n-------------\n\nSupports unicast, multicast or broadcast.  The following properties affect behavior - \nset them using Giulius' flexible settings mechanism (overlaid properties files in ``/etc/``,\n``~/`` and ``./``):\n\n * ``blurt.loopback.only`` - Only talk to the loopback network interface ``127.0.0.1``\n * ``blurt.udp.port`` - The UDP port to send messages to and listen on\n * ``blurt.udp.host`` - The host to send messages to.  Default is ``224.0.0.1`` for IPv4 and ``ff02::1`` for IPv6\n * ``blurt.udp.buffer.size`` - The size of the buffer to allocate for incoming packets;  the default is \n1024 bytes.  Note that how many bytes can actually be sent or received depends on the network topology - increasing\nthis value beyond the maximum possible UDP packet size on the network will simply waste memory.\n * ``blurt.udp.network.interface`` - The name of the network interface to listen to - the default is the first non-loopback\ninterface\n * ``blurt.enabled`` - If set to false, initialize but do not actually send or receive anything\n * ``blurt.autostart`` - Call ``BlurtControl.start()`` if a message is sent and it has not been called;  default is true.\n * ``blurt.upd.ipv6`` - Use IPv6\n * ``blurt.udp.thread.count`` - Number of threads to use for handing off messages.  The I/O loop is \nsingle-threaded NIO; when received, messages are dispatched to the bound ``BlurtReceiver`` on a thread pool.  t\n * ``blurt.heartbeat`` - If true, send a \"heartbeat\" uptime packet every so often to let monitoring applications\nknow the application is still alive\n * ``blurt.udp.multicast.loopback`` - Do multicast on the loopback interface\n * ``blurt.udp.broadcast`` - Use UDP broadcast\n * ``blurt.udp.multicast.ttl`` - Number of hops multicast packets should live\n * ``blurt.udp.traffic.class`` - Traffic class\n * ``blurt.send`` - If set to false, do not send messages, only listen\n * ``blurt.receive`` - If set to false, do not listen for messages, only send\n\n\nMaven\n-----\n\nTo use it from Maven, add [the Maven repository described here](http://timboudreau.com/builds)\nto your POM file, and then set a dependency, e.g.\n\n        \u003cdependency\u003e\n            \u003cgroupId\u003ecom.mastfrog\u003c/groupId\u003e\n            \u003cartifactId\u003eblurt\u003c/artifactId\u003e\n            \u003cversion\u003e1.3.9-SNAPSHOT\u003c/version\u003e\n        \u003c/dependency\u003e\n\nCheck the POM file linked above for the current version.\n\n\nBlurt for NodeJS\n----------------\n\nThe NodeJS implementation interoperates with the Java implementation.  Usage is\nsimilarly simple.  The following defaults are comparable to the ones above;\npass an object to ``Blurt``'s constructor to override it.\n\n        var defaults = {\n            host: \"224.0.0.1\",\n            port: 41234,\n            heartbeat: true,\n            interval: 10000,\n            ipv6: false,\n            bson: false,\n            autostart: true,\n            multicastLoopback: true,\n            multicastTtl: 2,\n            send: true,\n            receive: true,\n            bson: false\n        };\n\nThe javascript ``Blurt`` is a standard ``EventEmitter``; like the Java version,\nyou pass an object to the ``blurt()`` method.\n\nFor example:\n\n        var Blurt = require('blurt'), util = require('util');\n        var blurt = new Blurt({ ipv6 : true, host : 'ff02::1'});\n\n        blurt.on('message', function (obj, app, remoteInfo) {\n            console.log(\"Hey, I got a \" + util.inspect(obj));\n        });\n\n        blurt.blurt({ someNumber : 23, aMessage : 'hello blurt'});\n\n\nUnique IDs\n----------\n\nEach blurt message contains information about the origin application - its\nname, a unique ID generated and saved the first time it is run (in ``~/.$APPLICATION_NAME``),\nand an \"instance id\" which is an ID regenerated on startup.  This, combined with\nthe origin IP address, is enough information to identify which application \nsent the message, which machine and which run of that application sent it.\nThis information is helpful if doing shared logging or performance event\ncollection.\n\nThe strings are simply random characters which are generated, and can be\nmapped back to the originating application, and can be used to distinguish\nmultiple instances of the same application on the same machine or cluster.\n\nThey are also what Blurt uses, in a multicast or broadcast situation,\nto avoid sending you packets that were sent from the same process they\nare received in.\n\n\nBSON instead of JSON\n--------------------\n\nUDP has limitations on packet size, so to fit the most information into the smallest\nnumber of bytes, [BSON](http://bsonspec.org/) (the binary JSON format [MongoDB](http://mongodb.org) uses) is\nsupported, which significantly reduces the number of bytes needed for packets, particularly\nin the case of strings which cost extra bytes for quotes.\n\nTo enable BSON in the Java version, bind the following with Guice:\n\n       bind(BlurtCodec.class).to(BsonCodec.class);\n\nTo enable BSON in the Javascript version, set the ``bson`` property to ``true`` in the\nconfiguration object you pass to the ``Blurt`` constructor.\n\nOther codecs are possible (for example, an encrypting wrapper) are possible;  it is\nimportant, however, to respect the length limitations of UDP packets.\n\n\nWhat Goes Over The Wire\n-----------------------\n\nThe object you pass to ``blurt()`` (which should be a ``Map``, javascript hash or something, at any rate, that\ncan be resolved to key/value pairs) is simply serialized to JSON or BSON, with one little\naddition:  A key ``i`` is added (I know, I know, one letter variables - but we're trying to\nsave bytes here!) to the outgoing data, which contains the following:\n\n          $applicationId:$instanceId:$applicationName\n\nThese are stripped out of the payload you get back, and are passed to you separately.  This\ndoes mean that any property named ``i`` will be clobbered in payloads.\n\n\nA Last Word on UDP\n------------------\n\nUDP is appropriate for things where *packet loss is not catastrophic* - it trades away\nreliable delivery for message atomicity.  It's great when that is the right compromise\nfor the application.  It is not the right thing to use if packet loss *is* disasterous.\n\nIt would be possible to write an alternate transport (say using [ZeroMQ](http://zeromq.org/)\nwhich would still use this library's API.  Contributions are welcome!\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimboudreau%2Fblurt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimboudreau%2Fblurt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimboudreau%2Fblurt/lists"}