Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 156 lines (114 sloc) 6.975 kb
9d51e2c @kriszyp Started on docs
kriszyp authored
1 [Tunguska](http://en.wikipedia.org/wiki/Tunguska_event) is a comet-based
2 distributed publish/subscribe hub for server side JavaScript (Node, Rhino/Narwhal).
3 Tunguska is publish subscribe framework for
4 building applications around a publish-subscribe system with real-time message delivery
5 to browsers. Tunguska consists of several modules:
6
7 lib/hub.js
8d05d5c @kriszyp Updated docs
kriszyp authored
8 ========
9d51e2c @kriszyp Started on docs
kriszyp authored
9
10 This is the actual publish-subscribe hub. The hub is a simple, easy to use set of channels
11 for publishing and listening for events, but includes some powerful features. To use the
12 hub, simply require the hub.js module to get the hub object. If you installed Tunguska
13 such that lib/hub.js is available through the tunguska path:
14
15 var hub = require("tunguska/hub");
16
17 If you are using [Nodules](http://github.com/kriszyp/nodules) you can map to tunguska
18 by adding this line to your package.json (And Tunguska will automatically be downloaded for you):
19
87d5f40 @kriszyp Fixed spacing
kriszyp authored
20 "mappings": {
21 "tunguska": "jar:http://github.com/kriszyp/tunguska/zipball/master!/lib/"
22 }
9d51e2c @kriszyp Started on docs
kriszyp authored
23
24 Now to subscribe to a channel:
25
26 hub.subscribe("name/of/channel", function listenerFunction(message){
27 // do something with the messages that are received
28 });
29
30 To publish to a channel:
31
32 hub.publish("name/of/channel", {foo:"bar"});
33
34 And to unsubscribe:
35
36 hub.unsubscribe("name/of/channel", listenerFunction);
37
e32c610 @kriszyp Updated docs
kriszyp authored
38 Return Values
8d05d5c @kriszyp Updated docs
kriszyp authored
39 -------------
e32c610 @kriszyp Updated docs
kriszyp authored
40
41 Calls to publish, subscribe, and unsubscribe will return an array of promises that
42 represent the eventual return value from each subscriber. One can therefore determine
43 when all the messages have been delivered, and if there was failures. In a distributed
44 environment, the return value from subscription requests can be monitored to determine when the subscription
45 has been distributed to all hubs.
46
47 Globbing/Wildcards
8d05d5c @kriszyp Updated docs
kriszyp authored
48 -----------------
e32c610 @kriszyp Updated docs
kriszyp authored
49
9d51e2c @kriszyp Started on docs
kriszyp authored
50 Tunguska supports wildcarding/globbing for subscriptions. We can subscribe to a set
51 of channels like:
52
53 hub.subscribe("name/of/*", listenerFunction);
54
55 or we can use double asterisk for recursive wildcard, to subscribe to everything:
56
57 hub.subscribe("**", listenerFunction);
58
b8c4cfc @kriszyp Updated docs
kriszyp authored
59 Tunguska also supports named event sub-types within each channel. The subscribe
60 function takes an optional second parameter for specifying a specific event type
61 to listen for. For example,
9d51e2c @kriszyp Started on docs
kriszyp authored
62 we could choose to only listen to the "system" messages on a channel:
63
64 hub.subscribe("name/of/channel", "system", systemListener);
65
e32c610 @kriszyp Updated docs
kriszyp authored
66 Named Events
8d05d5c @kriszyp Updated docs
kriszyp authored
67 -------------
e32c610 @kriszyp Updated docs
kriszyp authored
68
69 And we can define name of the type of events with the "type" property in our published
9d51e2c @kriszyp Started on docs
kriszyp authored
70 messages. For example:
71
e32c610 @kriszyp Updated docs
kriszyp authored
72 hub.publish("name/of/channel", {type:"system"}); // will fire systemListener
73 hub.publish("name/of/channel", {type:"chat"}); // will not fire systemListener
9d51e2c @kriszyp Started on docs
kriszyp authored
74
75 Tunguska itself fires a special "monitored" event whenever a channel has one or more subscribers, and
76 whenever a channel becomes free of any subscribers. For example:
77
78 hub.subscribe("name/of/channel", "monitored", function(message){
79 if(message.monitored){
80 // name/of/channel has at least one subscriber now
81 }else{
82 // name/of/channel has no subscribers now
83 }
84 });
85
e32c610 @kriszyp Updated docs
kriszyp authored
86 (This is used by the connectors)
87
88 Client Identity/Echo Suppression
8d05d5c @kriszyp Updated docs
kriszyp authored
89 -----------------------------
9d51e2c @kriszyp Started on docs
kriszyp authored
90
91 Tunguska provides echo suppression by defining client identities. This is an important
92 feature for distributed pubsub because it allows you to define efficient message routing
b8c4cfc @kriszyp Updated docs
kriszyp authored
93 without messages bouncing back and forth. To define a client identity, you can call
e32c610 @kriszyp Updated docs
kriszyp authored
94 fromClient with a client id, which will return a new hub interface which will
b8c4cfc @kriszyp Updated docs
kriszyp authored
95 suppress all messages from this client. :
9d51e2c @kriszyp Started on docs
kriszyp authored
96
b8c4cfc @kriszyp Updated docs
kriszyp authored
97
98 hub.fromClient("client-1").subscribe("name/of/channel", function listenerFunction(message){
9d51e2c @kriszyp Started on docs
kriszyp authored
99 // do something with the messages that are received
b8c4cfc @kriszyp Updated docs
kriszyp authored
100 });
9d51e2c @kriszyp Started on docs
kriszyp authored
101
87d5f40 @kriszyp Fixed spacing
kriszyp authored
102 The clientId property may be an array if there are a list of client of client identities that
103 should be excluded.
104
e32c610 @kriszyp Updated docs
kriszyp authored
105 The hub interface returned from the fromClient call can also be used to publish messages.
b8c4cfc @kriszyp Updated docs
kriszyp authored
106 A message with a from a client will be withheld from any listener defined through that
107 client. For example:
9d51e2c @kriszyp Started on docs
kriszyp authored
108
b8c4cfc @kriszyp Updated docs
kriszyp authored
109 hub.fromClient("client-1").publish("name/of/channel", {name:"msg-1"}); // will not fire the listenerFunction above
110 hub.fromClient("client-2").publish("name/of/channel", {name:"msg-2"}); // will fire the listenerFunction
9d51e2c @kriszyp Started on docs
kriszyp authored
111
b8c4cfc @kriszyp Updated docs
kriszyp authored
112 lib/jsgi/comet.js
8d05d5c @kriszyp Updated docs
kriszyp authored
113 ============
9d51e2c @kriszyp Started on docs
kriszyp authored
114
115 This module consists of several JSGI appliances.
116
e32c610 @kriszyp Updated docs
kriszyp authored
117 * require("tunguska/jsgi/comet").Connections(nextApp) - This a middleware appliance for creating and
b8c4cfc @kriszyp Updated docs
kriszyp authored
118 using a pool of client connection entities that can be shared across requests. This can
119 be useful to use directly if non-comet requests may add or alter subscriptions for
120 another comet connection that shares the same virtual connection entity. Connections
121 are defined by including a "Client-Id" header in a request. All requests that share the
122 same Client-Id share the same connection object. The nextApp is called after connection
123 handling.
124
125 Connections are available within downstream JSGI applications from
126 request.clientConnection. The connection queue object has the following properties/methods:
e32c610 @kriszyp Updated docs
kriszyp authored
127 ** send(message) - This can be called to send a message to any connected client
128 ** onclose() - This event is called/triggered when a connection is closed
b8c4cfc @kriszyp Updated docs
kriszyp authored
129
130 * require("tunguska/jsgi/comet").Broadcaster(path, subscriptionApp, nextApp) - This
131 provides a comet end-point. A request that matches the path will be handled by the
132 Broadcaster and any messages in the client connection queue will be sent to the client,
133 or if the connection queue is empty, it will wait until a message is sent to the connection
134 and the broadcaster will deliver the message to the client. When the path is matched,
135 the subscriptionApp will be called next and can handle defining any subscriptions that
136 should be made (to the hub) and routing received messages to the connection queue.
137 If the path is not matched, the nextApp is called.
138
139 * require("tunguska/jsgi/comet").Subscriber(subscriptions, nextApp) - This is a
140 subscription handling appliance that will either use list of subscriptions provided in the
141 setup argument, or if the subscriptions argument is omitted, any subscriptions
142 provided in the request, and subscribes to given channels on the hub, and forwards any received messages
143 to the connection queue object.
144
145 * require("tunguska/jsgi/comet").Notifications(path, subscriptions, nextApp) - This combines
146 all three middleware appliance above into a single middleware appliance. The path defines
147 the comet end-point. The subscriptions parameter is optional and can specify the set
148 of channels to subscribe to. The nextApp is called for requests that don't match the path.
149
150 Connectors
8d05d5c @kriszyp Updated docs
kriszyp authored
151 =========
b8c4cfc @kriszyp Updated docs
kriszyp authored
152
153 Connectors provide a means for connecting hubs in different processes and on
154 different machines, thus allowing for distributed publish/subscribe systems. Connectors
155 are provided for worker-based communication and HTTP-based communication between
156 hubs.
Something went wrong with that request. Please try again.