{"_id":"tunguska","_rev":"11-17e903f7a8cbc815c4aa2eef0124641b","name":"tunguska","description":"Distributed publish/subscribe hub with Comet-style delivery of messages to browsers","dist-tags":{"latest":"0.3.0"},"versions":{"0.2.2":{"name":"tunguska","author":{"name":"Kris Zyp"},"version":"0.2.2","dependencies":{"patr":">=0.2.1"},"keywords":["comet","pubsub"],"githubName":"tunguska","mappings":{"patr":"http://github.com/kriszyp/patr/zipball/v0.2.1"},"licenses":[{"type":"AFLv2.1","url":"http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"},{"type":"BSD","url":"http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"}],"repository":{"type":"git","url":"http://github.com/kriszyp/tunguska"},"contributors":[],"directories":{"lib":"./lib"},"readme":"[Tunguska](http://en.wikipedia.org/wiki/Tunguska_event) is a comet-based \ndistributed publish/subscribe hub for server side JavaScript (Node, Rhino/Narwhal).\nTunguska is publish subscribe framework for building applications around a \npublish-subscribe system with real-time message delivery\nto browsers. An introduction to Tunguska can be [found here](http://www.sitepen.com/blog/2010/07/19/real-time-comet-applications-on-node-with-tunguska/).\nTunguska consists of several modules:\n\nlib/hub.js\n========\n\nThis is the actual publish-subscribe hub. The hub is a simple, easy to use set of channels\nfor publishing and listening for events, but includes some powerful features. To use the\nhub, simply require the hub.js module to get the hub object. If you installed Tunguska\nsuch that lib/hub.js is available through the tunguska path:\n\n    var hub = require(\"tunguska/hub\");\n\nIf you are using [Nodules](http://github.com/kriszyp/nodules) you can map to tunguska\nby adding this line to your package.json (And Tunguska will automatically be downloaded for you):\n\n    \"mappings\": {\n\t  \"tunguska\": \"jar:http://github.com/kriszyp/tunguska/zipball/master!/lib/\"\n    }\n\nNow to subscribe to a channel:\n\n    hub.subscribe(\"name/of/channel\", function listenerFunction(message){\n        // do something with the messages that are received\n    });\n\nTo publish to a channel:\n\n    hub.publish(\"name/of/channel\", {foo:\"bar\"});\n    \nAnd to unsubscribe:\n\n    hub.unsubscribe(\"name/of/channel\", listenerFunction);\n\nReturn Values\n-------------\n\nCalls to publish, subscribe, and unsubscribe will return an array of promises that \nrepresent the eventual return value from each subscriber. One can therefore determine\nwhen all the messages have been delivered, and if there was failures. In a distributed\nenvironment, the return value from subscription requests can be monitored to determine when the subscription\nhas been distributed to all hubs.\n\nGlobbing/Wildcards\n-----------------\n\nTunguska supports wildcarding/globbing for subscriptions. We can subscribe to a set\nof channels like:\n\n    hub.subscribe(\"name/of/*\", listenerFunction);\n\nor we can use double asterisk for recursive wildcard, to subscribe to everything:\n\n    hub.subscribe(\"**\", listenerFunction);\n\nTunguska also supports named event sub-types within each channel. The subscribe\nfunction takes an optional second parameter for specifying a specific event type\nto listen for. For example,\nwe could choose to only listen to the \"system\" messages on a channel:\n\n    hub.subscribe(\"name/of/channel\", \"system\", systemListener);\n \nNamed Events\n-------------\n\nAnd we can define name of the type of events with the \"type\" property in our published \nmessages. For example:\n\n    hub.publish(\"name/of/channel\", {type:\"system\"}); // will fire systemListener\n    hub.publish(\"name/of/channel\", {type:\"chat\"}); // will not fire systemListener\n\nTunguska itself fires a special \"monitored\" event whenever a channel has one or more subscribers, and\nwhenever a channel becomes free of any subscribers. For example:\n\n    hub.subscribe(\"name/of/channel\", \"monitored\", function(message){\n      if(message.monitored){\n        // name/of/channel has at least one subscriber now\n      }else{\n        // name/of/channel has no subscribers now\n      }\n    });\n\n(This is used by the connectors) \n\nClient Identity/Echo Suppression\n-----------------------------\n    \nTunguska provides echo suppression by defining client identities. This is an important\nfeature for distributed pubsub because it allows you to define efficient message routing\nwithout messages bouncing back and forth. To define a client identity, you can call\nfromClient with a client id, which will return a new hub interface which will\nsuppress all messages from this client. :\n\n    \n    hub.fromClient(\"client-1\").subscribe(\"name/of/channel\", function listenerFunction(message){\n        // do something with the messages that are received\n    });\n\nThe clientId property may be an array if there are a list of client of client identities that \nshould be excluded.\n\nThe hub interface returned from the fromClient call can also be used to publish messages.\nA message with a from a client will be withheld from any listener defined through that \nclient. For example:\n\n    hub.fromClient(\"client-1\").publish(\"name/of/channel\", {name:\"msg-1\"}); // will not fire the listenerFunction above\n    hub.fromClient(\"client-2\").publish(\"name/of/channel\", {name:\"msg-2\"}); // will fire the listenerFunction\n    \nlib/jsgi/comet.js\n============\n\nThis module consists of several JSGI appliances.\n\n* require(\"tunguska/jsgi/comet\").Connections(nextApp) - This a middleware appliance for creating and\nusing a pool of client connection entities that can be shared across requests. This can\nbe useful to use directly if non-comet requests may add or alter subscriptions for \nanother comet connection that shares the same virtual connection entity. Connections\nare defined by including a \"Client-Id\" header in a request. All requests that share the\nsame Client-Id share the same connection object. The nextApp is called after connection\nhandling. \n\nConnections are available within downstream JSGI applications from \nrequest.clientConnection. The connection queue object has the following properties/methods:\n** send(message) - This can be called to send a message to any connected client\n** onclose() - This event is called/triggered when a connection is closed  \n\n* require(\"tunguska/jsgi/comet\").Broadcaster(path, subscriptionApp, nextApp) - This \nprovides a comet end-point. A request that matches the path will be handled by the\nBroadcaster and any messages in the client connection queue will be sent to the client,\nor if the connection queue is empty, it will wait until a message is sent to the connection\nand the broadcaster will deliver the message to the client. When the path is matched,\nthe subscriptionApp will be called next and can handle defining any subscriptions that\nshould be made (to the hub) and routing received messages to the connection queue.\nIf the path is not matched, the nextApp is called.      \n\n* require(\"tunguska/jsgi/comet\").Subscriber(subscriptions, nextApp) - This is a \nsubscription handling appliance that will either use list of subscriptions provided in the \nsetup argument, or if the subscriptions argument is omitted, any subscriptions \nprovided in the request, and subscribes to given channels on the hub, and forwards any received messages\nto the connection queue object.\n\n* require(\"tunguska/jsgi/comet\").Notifications(path, subscriptions, nextApp) - This combines\nall three middleware appliance above into a single middleware appliance. The path defines\nthe comet end-point. The subscriptions parameter is optional and can specify the set\nof channels to subscribe to. The nextApp is called for requests that don't match the path.\n \nConnectors\n=========\n\nConnectors provide a means for connecting hubs in different processes and on \ndifferent machines, thus allowing for distributed publish/subscribe systems. Connectors\nare provided for worker-based communication, WebSocket communication \n(and in the future, HTTP-based communication) between hubs. The connectors \ncommunicate through a framed stream, following the \nWebSocket API. One can easily use a WebSocket connection or one can use the \nframed stream connection provided by multi-node for connecting processes. Here\nis an example of connecting the processes initiated by multi-node for distributed \npub/sub across all the processes:\n\n    var multiNode = require(\"multi-node/multi-node\"),\n        Connector = require(\"tunguska/connector\").Connector;\n    // start the multiple processes\n    var nodes = multiNode.listen({port: 80, nodes: 4}, serverObject);\n    // add a listener for each connection to the other sibling process\n    nodes.addListener(\"node\", function(stream){\n      // create a new connector using the framed WS stream\n      Connector(\"local-workers\", multiNode.frameStream(stream));\n    });\n\nThe Connection constructor takes two arguments:\n\n    Connector(connectionId, framedWebSocketStream);\n\nThe connectionId identifies the source of the messages, and utilizes echo suppression\nto route messages properly. A message that is broadcast from one connection won't\nget rerouted back to the same connector/client causing duplicate messages. The \nsecond argument is the framed stream that follows the WebSocket API. \n\nOne can utilize different connectionIds to connect different networks for more sophisticated\ntopologies. For example, one could have a set of connectors for local processes with one id (\"local-workers\"),\nand a connector for a remote server with another id (\"servers\"). A message received the other\nserver would not be echoed back to that server, but it would properly get routed to \nthe local worker processes.","_id":"tunguska@0.2.2","description":"[Tunguska](http://en.wikipedia.org/wiki/Tunguska_event) is a comet-based  distributed publish/subscribe hub for server side JavaScript (Node, Rhino/Narwhal). Tunguska is publish subscribe framework for building applications around a  publish-subscribe system with real-time message delivery to browsers. An introduction to Tunguska can be [found here](http://www.sitepen.com/blog/2010/07/19/real-time-comet-applications-on-node-with-tunguska/). Tunguska consists of several modules:","dist":{"shasum":"a6a936617abdc7fea909f200e403e5cb196e6076","tarball":"https://registry.npmjs.org/tunguska/-/tunguska-0.2.2.tgz","integrity":"sha512-xcb0/1v+iE/SttNhWFdx/LcS0BgwJ+NDHWxZlnvw/4Bhp6tr+c6BBkPF8OUIKW3LXYErOwEmQNFGvOVGIyrbLg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCwZKbCIVq5KjH7k8eVSuhOmHLyJTRAiVD9rvLu19TtVgIgE2CcvimUUSwrsrnNLOxDsRSNYahCQ8ai0+tduAm+nbM="}]},"scripts":{},"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"0.3.0":{"name":"tunguska","author":{"name":"Kris Zyp"},"version":"0.3.0","description":"Distributed publish/subscribe hub with Comet-style delivery of messages to browsers","dependencies":{"promised-io":">=0.3.0"},"keywords":["comet","pubsub"],"githubName":"tunguska","mappings":{"patr":"http://github.com/kriszyp/patr/zipball/v0.2.1"},"licenses":[{"type":"AFLv2.1","url":"http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43"},{"type":"BSD","url":"http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13"}],"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"repository":{"type":"git","url":"http://github.com/kriszyp/tunguska"},"contributors":[],"directories":{"lib":"."},"devDependencies":{"patr":">0.2.6"},"readme":"[Tunguska](http://en.wikipedia.org/wiki/Tunguska_event) is a comet-based \ndistributed publish/subscribe hub for server side JavaScript (Node, Rhino/Narwhal).\nTunguska is publish subscribe framework for building applications around a \npublish-subscribe system with real-time message delivery\nto browsers. An introduction to Tunguska can be [found here](http://www.sitepen.com/blog/2010/07/19/real-time-comet-applications-on-node-with-tunguska/).\nTunguska consists of several modules:\n\nlib/hub.js\n========\n\nThis is the actual publish-subscribe hub. The hub is a simple, easy to use set of channels\nfor publishing and listening for events, but includes some powerful features. To use the\nhub, simply require the hub.js module to get the hub object. If you installed Tunguska\nsuch that lib/hub.js is available through the tunguska path:\n\n    var hub = require(\"tunguska/hub\");\n\nIf you are using [Nodules](http://github.com/kriszyp/nodules) you can map to tunguska\nby adding this line to your package.json (And Tunguska will automatically be downloaded for you):\n\n    \"mappings\": {\n\t  \"tunguska\": \"jar:http://github.com/kriszyp/tunguska/zipball/master!/lib/\"\n    }\n\nNow to subscribe to a channel:\n\n    hub.subscribe(\"name/of/channel\", function listenerFunction(message){\n        // do something with the messages that are received\n    });\n\nTo publish to a channel:\n\n    hub.publish(\"name/of/channel\", {foo:\"bar\"});\n    \nAnd to unsubscribe:\n\n    hub.unsubscribe(\"name/of/channel\", listenerFunction);\n\nReturn Values\n-------------\n\nCalls to publish, subscribe, and unsubscribe will return an array of promises that \nrepresent the eventual return value from each subscriber. One can therefore determine\nwhen all the messages have been delivered, and if there was failures. In a distributed\nenvironment, the return value from subscription requests can be monitored to determine when the subscription\nhas been distributed to all hubs.\n\nGlobbing/Wildcards\n-----------------\n\nTunguska supports wildcarding/globbing for subscriptions. We can subscribe to a set\nof channels like:\n\n    hub.subscribe(\"name/of/*\", listenerFunction);\n\nor we can use double asterisk for recursive wildcard, to subscribe to everything:\n\n    hub.subscribe(\"**\", listenerFunction);\n\nIn addition, we can use tagged subscriptions to subscribe to a subset of tagged messages on a channel:\n\n    hub.subscribe(\"name/of/*:tagname\", listenerFunction);\n\nUsing tags requires that objects are published with a tag:\n\n    hub.publish(\"name/of/channel:tagname\", {foo:\"bar\"});\n\nMessages that are published with a tag will be sent to all subscribers that are subscribed to a matching tag, or that are subscribed to the base channel without a tag.\n\nTunguska also supports named event sub-types within each channel. The subscribe\nfunction takes an optional second parameter for specifying a specific event type\nto listen for. For example,\nwe could choose to only listen to the \"system\" messages on a channel:\n\n    hub.subscribe(\"name/of/channel\", \"system\", systemListener);\n \nNamed Events\n-------------\n\nAnd we can define name of the type of events with the \"type\" property in our published \nmessages. For example:\n\n    hub.publish(\"name/of/channel\", {type:\"system\"}); // will fire systemListener\n    hub.publish(\"name/of/channel\", {type:\"chat\"}); // will not fire systemListener\n\nTunguska itself fires a special \"monitored\" event whenever a channel has one or more subscribers, and\nwhenever a channel becomes free of any subscribers. For example:\n\n    hub.subscribe(\"name/of/channel\", \"monitored\", function(message){\n      if(message.monitored){\n        // name/of/channel has at least one subscriber now\n      }else{\n        // name/of/channel has no subscribers now\n      }\n    });\n\n(This is used by the connectors) \n\nClient Identity/Echo Suppression\n-----------------------------\n    \nTunguska provides echo suppression by defining client identities. This is an important\nfeature for distributed pubsub because it allows you to define efficient message routing\nwithout messages bouncing back and forth. To define a client identity, you can call\nfromClient with a client id, which will return a new hub interface which will\nsuppress all messages from this client. :\n\n    \n    hub.fromClient(\"client-1\").subscribe(\"name/of/channel\", function listenerFunction(message){\n        // do something with the messages that are received\n    });\n\nThe clientId property may be an array if there are a list of client of client identities that \nshould be excluded.\n\nThe hub interface returned from the fromClient call can also be used to publish messages.\nA message with a from a client will be withheld from any listener defined through that \nclient. For example:\n\n    hub.fromClient(\"client-1\").publish(\"name/of/channel\", {name:\"msg-1\"}); // will not fire the listenerFunction above\n    hub.fromClient(\"client-2\").publish(\"name/of/channel\", {name:\"msg-2\"}); // will fire the listenerFunction\n    \nlib/jsgi/comet.js\n============\n\nThis module consists of several JSGI appliances.\n\n* require(\"tunguska/jsgi/comet\").Connections(nextApp) - This a middleware appliance for creating and\nusing a pool of client connection entities that can be shared across requests. This can\nbe useful to use directly if non-comet requests may add or alter subscriptions for \nanother comet connection that shares the same virtual connection entity. Connections\nare defined by including a \"Client-Id\" header in a request. All requests that share the\nsame Client-Id share the same connection object. The nextApp is called after connection\nhandling. \n\nConnections are available within downstream JSGI applications from \nrequest.clientConnection. The connection queue object has the following properties/methods:\n** send(message) - This can be called to send a message to any connected client\n** onclose() - This event is called/triggered when a connection is closed  \n\n* require(\"tunguska/jsgi/comet\").Broadcaster(path, subscriptionApp, nextApp) - This \nprovides a comet end-point. A request that matches the path will be handled by the\nBroadcaster and any messages in the client connection queue will be sent to the client,\nor if the connection queue is empty, it will wait until a message is sent to the connection\nand the broadcaster will deliver the message to the client. When the path is matched,\nthe subscriptionApp will be called next and can handle defining any subscriptions that\nshould be made (to the hub) and routing received messages to the connection queue.\nIf the path is not matched, the nextApp is called.      \n\n* require(\"tunguska/jsgi/comet\").Subscriber(subscriptions, nextApp) - This is a \nsubscription handling appliance that will either use list of subscriptions provided in the \nsetup argument, or if the subscriptions argument is omitted, any subscriptions \nprovided in the request, and subscribes to given channels on the hub, and forwards any received messages\nto the connection queue object.\n\n* require(\"tunguska/jsgi/comet\").Notifications(path, subscriptions, nextApp) - This combines\nall three middleware appliance above into a single middleware appliance. The path defines\nthe comet end-point. The subscriptions parameter is optional and can specify the set\nof channels to subscribe to. The nextApp is called for requests that don't match the path.\n \nConnectors\n=========\n\nConnectors provide a means for connecting hubs in different processes and on \ndifferent machines, thus allowing for distributed publish/subscribe systems. Connectors\nare provided for worker-based communication, WebSocket communication \n(and in the future, HTTP-based communication) between hubs. The connectors \ncommunicate through a framed stream, following the \nWebSocket API. One can easily use a WebSocket connection or one can use the \nframed stream connection provided by multi-node for connecting processes. Here\nis an example of connecting the processes initiated by multi-node for distributed \npub/sub across all the processes:\n\n    var multiNode = require(\"multi-node/multi-node\"),\n        Connector = require(\"tunguska/connector\").Connector;\n    // start the multiple processes\n    var nodes = multiNode.listen({port: 80, nodes: 4}, serverObject);\n    // add a listener for each connection to the other sibling process\n    nodes.addListener(\"node\", function(stream){\n      // create a new connector using the framed WS stream\n      Connector(\"local-workers\", multiNode.frameStream(stream));\n    });\n\nThe Connection constructor takes two arguments:\n\n    Connector(connectionId, framedWebSocketStream);\n\nThe connectionId identifies the source of the messages, and utilizes echo suppression\nto route messages properly. A message that is broadcast from one connection won't\nget rerouted back to the same connector/client causing duplicate messages. The \nsecond argument is the framed stream that follows the WebSocket API. \n\nOne can utilize different connectionIds to connect different networks for more sophisticated\ntopologies. For example, one could have a set of connectors for local processes with one id (\"local-workers\"),\nand a connector for a remote server with another id (\"servers\"). A message received the other\nserver would not be echoed back to that server, but it would properly get routed to \nthe local worker processes.","_id":"tunguska@0.3.0","dist":{"shasum":"d89c39e4374fe5f4de50bf0791410c3fdf1413d9","tarball":"https://registry.npmjs.org/tunguska/-/tunguska-0.3.0.tgz","npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2+ftCRA9TVsSAnZWagAA0gUP/i1Mvs6GJRR1WtitaXzx\n2/tip1QOLqYfMpTLlTCS3HJGx2jZ9ao5xBD5ZPE6/fFeFlnD626KvkDyZryn\ncCUWIE1TrKvOOwhZ9FsdN+JXN0a4CKfX5BV/vA3G75Sxqk4ckMCgWExJdO8y\noSonPFtTYZSyTaP644isrZVjEUsN/hXRogHXBrgbZskzVnObl50ZGPn7qN/v\nOypsnkDbxdX9AdpKTgpALZEBDKRsQxdIFRj3QOKJEo129qsQapB0uNEBASrb\n+TZTKceuNiqyOCqM4v/tiUGH0U+6DoAXUVMh8OZQTyeDRUGoktgcnMFUU3Jm\nDqGU/dNtxB9zsFn6CBABdGaopRbDxBhnp0N6h1B/vxeyXuXNCPJAJL1IMIIi\n7ynbX5fxQ2sPZF01IZ9qYZHsG1WIF0l4QSLNly8xv3uNerwBHer8Vhpa8Daa\nZRvqLPaLwqa9RqbLxg20IqOc6hxFAcr96QtloYm+gBU2OMFqb1KIpEHRR3B7\nNW2pfdRqEilATviFqliPxVzYIvQdf/H0QvNlbc26uXeQKL2T8FKtKCcesz9I\nOrY7cjQoV0+ovPPf/EeB3fc/h96tFYRny565HzvvSwjuSZo8Gq473333SYWA\n6DpwLRnm6r0usuFd64txvuazAPAdrtZf8l20C2/YFwRP70FXRBfFk6/11QkT\njAIB\r\n=jWwA\r\n-----END PGP SIGNATURE-----\r\n","integrity":"sha512-FmVY9CaRi2ECPnIgmwzPJJEIcfljBgGv5As7EVm5mO9vRpfDuu+TwBDe5mEb78Mi1HlDPGrNXOcEFarm3bxPfw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD7O+iXe3oJjBNHLziZglwUVhbP2AWBeuGLZeXgelvE9AIhAKpQey5K73X289+y2wldeZuuG4ftZt6lHRkdT3cN3r0u"}]},"scripts":{},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."}},"readme":"[Tunguska](http://en.wikipedia.org/wiki/Tunguska_event) is a comet-based \ndistributed publish/subscribe hub for server side JavaScript (Node, Rhino/Narwhal).\nTunguska is publish subscribe framework for building applications around a \npublish-subscribe system with real-time message delivery\nto browsers. An introduction to Tunguska can be [found here](http://www.sitepen.com/blog/2010/07/19/real-time-comet-applications-on-node-with-tunguska/).\nTunguska consists of several modules:\n\nlib/hub.js\n========\n\nThis is the actual publish-subscribe hub. The hub is a simple, easy to use set of channels\nfor publishing and listening for events, but includes some powerful features. To use the\nhub, simply require the hub.js module to get the hub object. If you installed Tunguska\nsuch that lib/hub.js is available through the tunguska path:\n\n    var hub = require(\"tunguska/hub\");\n\nIf you are using [Nodules](http://github.com/kriszyp/nodules) you can map to tunguska\nby adding this line to your package.json (And Tunguska will automatically be downloaded for you):\n\n    \"mappings\": {\n\t  \"tunguska\": \"jar:http://github.com/kriszyp/tunguska/zipball/master!/lib/\"\n    }\n\nNow to subscribe to a channel:\n\n    hub.subscribe(\"name/of/channel\", function listenerFunction(message){\n        // do something with the messages that are received\n    });\n\nTo publish to a channel:\n\n    hub.publish(\"name/of/channel\", {foo:\"bar\"});\n    \nAnd to unsubscribe:\n\n    hub.unsubscribe(\"name/of/channel\", listenerFunction);\n\nReturn Values\n-------------\n\nCalls to publish, subscribe, and unsubscribe will return an array of promises that \nrepresent the eventual return value from each subscriber. One can therefore determine\nwhen all the messages have been delivered, and if there was failures. In a distributed\nenvironment, the return value from subscription requests can be monitored to determine when the subscription\nhas been distributed to all hubs.\n\nGlobbing/Wildcards\n-----------------\n\nTunguska supports wildcarding/globbing for subscriptions. We can subscribe to a set\nof channels like:\n\n    hub.subscribe(\"name/of/*\", listenerFunction);\n\nor we can use double asterisk for recursive wildcard, to subscribe to everything:\n\n    hub.subscribe(\"**\", listenerFunction);\n\nTunguska also supports named event sub-types within each channel. The subscribe\nfunction takes an optional second parameter for specifying a specific event type\nto listen for. For example,\nwe could choose to only listen to the \"system\" messages on a channel:\n\n    hub.subscribe(\"name/of/channel\", \"system\", systemListener);\n \nNamed Events\n-------------\n\nAnd we can define name of the type of events with the \"type\" property in our published \nmessages. For example:\n\n    hub.publish(\"name/of/channel\", {type:\"system\"}); // will fire systemListener\n    hub.publish(\"name/of/channel\", {type:\"chat\"}); // will not fire systemListener\n\nTunguska itself fires a special \"monitored\" event whenever a channel has one or more subscribers, and\nwhenever a channel becomes free of any subscribers. For example:\n\n    hub.subscribe(\"name/of/channel\", \"monitored\", function(message){\n      if(message.monitored){\n        // name/of/channel has at least one subscriber now\n      }else{\n        // name/of/channel has no subscribers now\n      }\n    });\n\n(This is used by the connectors) \n\nClient Identity/Echo Suppression\n-----------------------------\n    \nTunguska provides echo suppression by defining client identities. This is an important\nfeature for distributed pubsub because it allows you to define efficient message routing\nwithout messages bouncing back and forth. To define a client identity, you can call\nfromClient with a client id, which will return a new hub interface which will\nsuppress all messages from this client. :\n\n    \n    hub.fromClient(\"client-1\").subscribe(\"name/of/channel\", function listenerFunction(message){\n        // do something with the messages that are received\n    });\n\nThe clientId property may be an array if there are a list of client of client identities that \nshould be excluded.\n\nThe hub interface returned from the fromClient call can also be used to publish messages.\nA message with a from a client will be withheld from any listener defined through that \nclient. For example:\n\n    hub.fromClient(\"client-1\").publish(\"name/of/channel\", {name:\"msg-1\"}); // will not fire the listenerFunction above\n    hub.fromClient(\"client-2\").publish(\"name/of/channel\", {name:\"msg-2\"}); // will fire the listenerFunction\n    \nlib/jsgi/comet.js\n============\n\nThis module consists of several JSGI appliances.\n\n* require(\"tunguska/jsgi/comet\").Connections(nextApp) - This a middleware appliance for creating and\nusing a pool of client connection entities that can be shared across requests. This can\nbe useful to use directly if non-comet requests may add or alter subscriptions for \nanother comet connection that shares the same virtual connection entity. Connections\nare defined by including a \"Client-Id\" header in a request. All requests that share the\nsame Client-Id share the same connection object. The nextApp is called after connection\nhandling. \n\nConnections are available within downstream JSGI applications from \nrequest.clientConnection. The connection queue object has the following properties/methods:\n** send(message) - This can be called to send a message to any connected client\n** onclose() - This event is called/triggered when a connection is closed  \n\n* require(\"tunguska/jsgi/comet\").Broadcaster(path, subscriptionApp, nextApp) - This \nprovides a comet end-point. A request that matches the path will be handled by the\nBroadcaster and any messages in the client connection queue will be sent to the client,\nor if the connection queue is empty, it will wait until a message is sent to the connection\nand the broadcaster will deliver the message to the client. When the path is matched,\nthe subscriptionApp will be called next and can handle defining any subscriptions that\nshould be made (to the hub) and routing received messages to the connection queue.\nIf the path is not matched, the nextApp is called.      \n\n* require(\"tunguska/jsgi/comet\").Subscriber(subscriptions, nextApp) - This is a \nsubscription handling appliance that will either use list of subscriptions provided in the \nsetup argument, or if the subscriptions argument is omitted, any subscriptions \nprovided in the request, and subscribes to given channels on the hub, and forwards any received messages\nto the connection queue object.\n\n* require(\"tunguska/jsgi/comet\").Notifications(path, subscriptions, nextApp) - This combines\nall three middleware appliance above into a single middleware appliance. The path defines\nthe comet end-point. The subscriptions parameter is optional and can specify the set\nof channels to subscribe to. The nextApp is called for requests that don't match the path.\n \nConnectors\n=========\n\nConnectors provide a means for connecting hubs in different processes and on \ndifferent machines, thus allowing for distributed publish/subscribe systems. Connectors\nare provided for worker-based communication, WebSocket communication \n(and in the future, HTTP-based communication) between hubs. The connectors \ncommunicate through a framed stream, following the \nWebSocket API. One can easily use a WebSocket connection or one can use the \nframed stream connection provided by multi-node for connecting processes. Here\nis an example of connecting the processes initiated by multi-node for distributed \npub/sub across all the processes:\n\n    var multiNode = require(\"multi-node/multi-node\"),\n        Connector = require(\"tunguska/connector\").Connector;\n    // start the multiple processes\n    var nodes = multiNode.listen({port: 80, nodes: 4}, serverObject);\n    // add a listener for each connection to the other sibling process\n    nodes.addListener(\"node\", function(stream){\n      // create a new connector using the framed WS stream\n      Connector(\"local-workers\", multiNode.frameStream(stream));\n    });\n\nThe Connection constructor takes two arguments:\n\n    Connector(connectionId, framedWebSocketStream);\n\nThe connectionId identifies the source of the messages, and utilizes echo suppression\nto route messages properly. A message that is broadcast from one connection won't\nget rerouted back to the same connector/client causing duplicate messages. The \nsecond argument is the framed stream that follows the WebSocket API. \n\nOne can utilize different connectionIds to connect different networks for more sophisticated\ntopologies. For example, one could have a set of connectors for local processes with one id (\"local-workers\"),\nand a connector for a remote server with another id (\"servers\"). A message received the other\nserver would not be echoed back to that server, but it would properly get routed to \nthe local worker processes.","maintainers":[{"name":"kriszyp","email":"kriszyp@gmail.com"}],"time":{"modified":"2022-06-27T23:19:46.183Z","created":"2012-07-06T22:02:00.622Z","0.2.2":"2012-07-06T22:02:01.882Z","0.3.0":"2012-07-06T22:02:05.531Z"},"author":{"name":"Kris Zyp"},"repository":{"type":"git","url":"http://github.com/kriszyp/tunguska"}}