-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathREADME
233 lines (146 loc) · 6.37 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/ _| __ _ _ __ ___ _ _| |_ (_)___
| |_ / _` | '_ \ / _ \| | | | __| | / __|
| _| (_| | | | | (_) | |_| | |_ _ | \__ \
|_| \__,_|_| |_|\___/ \__,_|\__(_)_/ |___/
|__/
================================================================================
1 2 3 4 5 6 7 8
1...5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
fanout.js - a simple and robust fanout pubsub
messaging server for node.js by @jazzychad
MOTIVATION
==========
I needed a robust and scalable event-driven message fanout server for several
Comet-based webapps where some process in the backend could send various
messages of different types/channels to the clients (browsers) in the front-end.
fanout.js implements such a server using standard TCP sockets so that it can be
used in a wide variety of applications. Connection to web browsers is
accomplished by using the TCPSocket abstraction in the Orbited.org project.
For a live example of fanout.js in use, check out http://4squarevision.com/
I have serveral webapps using this system. One has been running strong for
5 months without ever having to restart the node.js process.
OVERVIEW
========
The fanout pubsub system consists of three parts
o The "fanout server" itself
o One or more "Clients" (message subscribers)
o One or more "Controllers" (message publishers)
The fanout server is run as a node.js process. Clients connect to the server on
the client port (default 8880). Controllers connect to the server on the
controller port (default 8890).
Clients can do 4 (four) things:
o Subscribe to message channels
o Unsubscribe from message channels
o Receive messages on subscribed message channels
o Ping the fanout server for the current unix millitime
Controllers can do 1 (one) thing:
o Send (publish) messages on message channels
Upon connection, each Client is automatically subscribed to the "all" message
channel, so that if a Controller publishes a message to the "all" message
channel, each Client will receive it. This is useful for sending system-wide
messages to all connected clients. Clients can choose to unsubscribe from the
"all" channel if they so choose. Also upon connection, each client will receive
a message on the "debug" message channel notifying them that they have connected
to the server.
CLIENT PROTOCOL
===============
Subscribing
-----------
Clients subscribe to a message channel by sending a message of the format:
subscribe<space><channel_name>
Message channel names are one word tokens which may not include spaces.
Example:
subscribe foo
will subscribe to the client to the message channel called foo
If a client subscribes to a channel for which it is already subscribed,
the duplicate subscribe request is effectively ignored.
Unsubscribing
-------------
Client unsubscribe to a message channel by sending a message of the format:
unsubscribe<space><channel_name>
The message channel name must match exactly the name of the channel to which
the client is already subscribed (it is case-sensitive).
Example:
unsubscribe foo
will unsubscribe the client from the message channel called foo
Sending an unsubscribe request for a message channel to which the client is
not already subscribed is effectively treated as a no-op.
Ping the Server
---------------
Clients may ping the fanout server by sending a special message:
time
The server will respond with the current time as milliseconds elapsed since
the Unix Epoch.
Receiving Messages
------------------
Once a Client subscribes to one or more message channels, when a Controller
publishes messages to those specific channels, the Client will automatically
receive the message in the format:
<channel_name>!<message><newline_character>
Example:
A controller sends the message "hello, world" to the message channel "foo".
The clients subscribed to "foo" will receive the following message:
foo!hello, world
(including a final newline character to signify the end of the message).
CONTROLLER PROTOCOL
===================
Publishing a Message
--------------------
Controllers publish messages to message channels in the following format:
<channel_name><space><message><newline>
Example:
A Controller wants to send the message "hello, world" to the message
channel called "foo".
foo hello, world
(including a final newline character to signify the end of the message).
The first word of Controller messages is always taken to mean the destination
message channel. Everything after the first space is taken as the message
to publish on that channel.
Message channels are "soft" in that they do not need to be declared or
otherwise created prior to publishing messages on them. If a Controller
publishes a message to a channel with no subscribers, the message is
effectively dropped.
USAGE
=====
Assuming you have installed node.js on your machine/server, all you need
is this:
node fanout.js
EXAMPLE
=======
Open 4 (four) terminal windows.
In Terminal 1, run fanout.js
node fanout.js
In Terminal 2, connect as a Controller
netcat localhost 8890
In Terminal 3, connect as a Client
netcat localhost 8880
In Terminal 4, connect as another Client
netcat localhost 8880
In terminal 2, type
all hello everybody
and hit return. You should see "all!hello everybody" appear in both
Terminal 3 and 4.
In Terminal 3, type
subscribe aaa
and hit return. In Terminal 4, type
subscribe bbb
and hit return.
In Terminal 2, type
aaa only one client should see this
and hit return. You should see the message received by Terminal 3.
In Terminal 2, type
bbb only the other client should see this
and hit return. You should see the message received by Terminal 4.
In Terminal 2, type
ccc nobody should see this message
and hit return. Since there are no subscribers to the "ccc" channel, it will
not be received by any clients.
In Terminal 3, type
unsubscribe aaa
and hit return. In Terminal 2, type
aaa will anyone see this now? nope...
and hit return. Since Terminal 3 just unsubscribed from "aaa" it should not
receive the message.
Continue experimenting with different subscribe/unsubscribe commands from the
Clients and publishing different messages on different channels with the
Controller. You should figure out the basic use rather quickly.