-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProtocol.txt
More file actions
318 lines (248 loc) · 7.75 KB
/
Copy pathProtocol.txt
File metadata and controls
318 lines (248 loc) · 7.75 KB
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
Protocol
NOTE: To get a UTC timestamp in milliseconds:
return Calendar.getInstance().getTimeInMillis();
Room: (/[a-zA-Z0-9_]+) alphanumeric + underscore words separated by /'s)
Alias: [a-zA-Z0-9_]+ alphanumeric + underscore word
Number: [1-9][0-9]* integer
RingNumber: Number (Int32)
ServerNumber: Number (Int32)
ClientNumber: Number (Int32)
Priority: Number (Int32)
MessageLength: Number (Int32)
ServerAddress: DNS name or IP address
Port: Number from 1 through 65535 inclusive
Server ID: RingNumber.ServerNumber
Client ID: [Room].ClientNumber Salt is used to randomize fallback server
Message ID: [Client ID]:Number Number should be strictly increasing for subsequent messages from same client
UTC timestamp: [milliseconds since epoch as Int64]
================================================================================
Ring protocol
================================================================================
========================================
Status ping
========================================
1. Started by head node, continued from predecessor to successor until it
returns to the head node.
P:
RINGSTAT\n
Source: [Server ID]
Statuses: {[Server ID] [Server Address] [Port] [Health]|}*\n
Rooms: {[Room] [Cumulative client count]|}*\n
Migrations: {[Room], {[Server ID] [Server Address] [Port] [Health]|}*&}*
\n
For migrations, the ',', '|', and '&' are separators.
Note that every forwarding node has complete topological information about the
ring from the status updates because Server ID's are in strictly increasing
order, with the minimum ID being the head node.
========================================
Message forwarding
========================================
1. Started by receiving node, continued around loop until receiving node
receives its own message.
P:
FORWARD\n
Source: [Server ID]
Time: [UTC Timestamp]
Sender: [Client ID]\n
Alias: [Alias]\n
Room: [Room]\n
MessageID: [Message ID]\n
\n
[Message]
2. When receiving node receives its own forwarding (loop is complete), it sends
the ACK to the client.
3. Each server in the ring sends a MESG notification to all of its clients in
the relevant rooms.
========================================
Inserting a new server into the ring
========================================
0. Only the head node can order a new server to be added.
1. Node chooses a predecessor to reinsert itself after.
2. Node sends update to predecessor
N:
INSERT_AFTER\n
Server: [Server ID] [Server Address] [Port]\n
\n
P:
INSERT_ACK\n
\n
3. Node sends update to successor
N:
INSERT_BEFORE\n
Server: [Server ID] [Server Address] [Port]\n
\n
S:
INSERT_ACK\n
\n
4. Before INSERT_ACK from predecessor, Node assumes that it's not in the ring.
After INSERT_ACK from predecessor:
Before INSERT_ACK from successor, Node forwards status pings without including itself.
After INSERT_ACK from successor, Node includes itself in status pings to make it visible to the ring.
5. Predecessor sends message histories.
========================================
Sending message histories
========================================
1. Sender sends set of FORWARD messages to receiver for each relevant room.
In the case of adding a node, the predecessor to the inserted node forwards
ALL of its histories to the new node.
In the case of migrating a room, the original room sends the history for the
migrating room to the new node.
========================================
Create new room
========================================
1. Pick most idle ring. Send packet to head node of idle ring:
C:
CREATE\n
Room: [Room]\n
\n
2. Head node adds room to status ping.
3. Room is active when status ping goes full circle.
S:
CREATED\n
Room: [Room]\n
\n
========================================
Room death
========================================
1. Head node sends status ping
2. Ping returns with a 0-member room.
3. Head node removes room from status ping's room list.
4. Forwarding nodes remove room on next ping.
================================================================================
Halo protocol
================================================================================
========================================
Halo status pings
========================================
1. Every halo's head node has a n millisecond delay.
2. Forwards a status ping:
S:
HALOSTAT\n
Health: {[Ring ID] [Server ID] [Server Address] [Port] [Health]|}*\n
\n
3. Each server updates its own entry and forwards after the delay.
TODO: How to choose where to migrate a room.
TODO: How to add new room.
========================================
Find Room
========================================
1. Head node checks own rooms.
2. Head node checks successor:
H:
SEARCH\n
Room: [Room]\n
\n
3. Successor returns authentication result if it owns room:
S:
ROOM\n
Client: [Client ID]\n
Servers: {[Priority] [Server ID] [Server Address] [Port]|}*\n
\n
If successor does not own room:
S:
NOROOM\n
Room: [Room]\n
\n
4. If successor does not own room, then check with the successor of the successor, repeat step 3.
5. On positive result, relay authentication info to client in a FOUND message.
========================================
Migrate room
========================================
1. Head node from source ring creates new room in target ring.
2. Head node from source ring removes room from its own public listing.
3. Head node forwards history to new head node.
4. Head node sends status ping that includes the migration order.
5. Head node forwards all new messages into the new head node until old room
reports 0 members.
6. Head node removes room from status ping listing, stops forwarding to new room.
7. migration is complete.
================================================================================
Client-Server protocol
================================================================================
========================================
Authentication:
========================================
C:
FIND\n
Room: [Room]\n
\n
S:
FOUND\n
Client: [Client ID]\n
Servers: {[Priority] [Server ID] [Server Address] [Port]|}*\n
Room: [Room]\n
\n
========================================
Open connection:
========================================
C:
CONN\n
Client: [Client ID]\n
Room: [Room]\n
\r\n
S:
OK\n
ServerID: [Server ID]\n
Servers: {[Priority] [Server ID] [Server Address] [Port]|}*\n
Room: [Room]\n
Time: [UTC timestamp]
\n
========================================
Recover connection:
========================================
C:
RECONN\n
Client: [Client ID]\n
Room: [Room]\n
LastAcked: [UTC timestamp]\n
LastReceived: [UTC timestamp]\n
\n
S:
OK\n
ServerID: [Server ID]\n
Servers: {[Priority] [Server ID] [Server Address] [Port]|}*\n
Room: [Room]\n
Time: [UTC timestamp]
\n
NOTE: After ack, Client attempts to SEND all unacknowledged messages,
and Server attempts to MESG all unreceived messages.
========================================
Send message
========================================
C:
SEND\n
Sender: [Client ID]\n
Alias: [Alias]\n
Room: [Room]\n
MessageID: [Message ID]\n
\n
[Message]
S:
ACK\n
ServerID: [Server ID]\n
Servers: {[Priority] [Server ID] [Server Address] [Port]|}*\n
Room: [Room]\n
Time: [UTC timestamp]
\n
========================================
Notify message
========================================
S:
MESG\n
ServerID: [Server ID]\n
Servers: {[Priority] [Server ID] [Server Address] [Port]|}*\n
Time: [UTC timestamp]\n
Sender: [Client ID]\n
Alias: [Alias]\n
Room: [Room]\n
MessageID: [Message ID]\n
\n
[Message]
========================================
Update fallbacks
========================================
S:
UPDT\n
ServerID: [Server ID]\n
Servers: {[Priority] [Server ID] [Server Address] [Port]|}*\n
Room: [Room]\n