-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathchat.js
96 lines (87 loc) · 2.96 KB
/
chat.js
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
"use strict";
var talk = document.getElementById('talk'),
send = document.getElementById('send'),
chat_history = document.getElementById('chat_history');
function updateHistory() {
var lines = node._self.stateMachine['history'];
if (lines) {
chat_history.innerHTML = lines.value.join("\n");
}
}
function applyCmd(stateMachine, cmd) {
//log("applyCmd:", JSON.stringify(cmd));
switch (cmd.op) {
case 'get':
stateMachine[cmd.key];
return stateMachine[cmd.key];
case 'set':
stateMachine[cmd.key] = cmd.value;
return stateMachine[cmd.key];
case 'seqAppend':
// Returns a tuple of [success, curCnt, msg] or an
// exception if the command is not a valid appendSeq or
// the target key is not a sequence.
if (!'key' in cmd) { throw new Error("seqAppend missing 'key'") }
if (!'value' in cmd) { throw new Error("seqAppend missing 'value'") }
if (!'cnt' in cmd) { throw new Error("seqAppend missing 'cnt'") }
// Add the sequence key if it's not already there
if (!(cmd.key in stateMachine)) {
stateMachine[cmd.key] = {cnt: 0, value: []};
}
var seq = stateMachine[cmd.key];
if (!('cnt' in seq && 'value' in seq)) {
throw new Error("seqAppend on non-sequence");
}
if (cmd.cnt !== seq.cnt) {
return [false, seq.cnt];
} else {
seq.value.push(cmd.value);
seq.cnt += 1;
setTimeout(updateHistory, 1);
return [true, seq.cnt];
}
}
}
var sendTimeout = 100,
sendTimer = null,
curSeqCnt = 0,
curSend = null,
pendingSends = [];
function flushSends() {
sendTimer = setTimeout(flushSends, sendTimeout);
if (curSend || pendingSends.length === 0) { return; }
var curSend = pendingSends.shift(),
req = {op: 'seqAppend',
key: 'history',
cnt: curSeqCnt,
value: curSend};
clientRequest(req, function(result) {
//console.log("result:", JSON.stringify(result));
if (result.status !== 'success' || result.result[0] === false) {
console.log("retrying seqAppend with cnt: " + result.result[1]);
pendingSends.unshift(curSend);
} else {
// After a successful send, try again immediately
clearTimeout(sendTimer);
sendTimer = setTimeout(flushSends, 1);
}
curSend = null;
curSeqCnt = result.result[1];
});
}
function sendLine() {
var line = nodeId + ": " + talk.value;
talk.value = "";
pendingSends.push(line);
}
function startChat() {
send.onclick = sendLine;
// Also send on enter
talk.onkeyup = function(e) {
if (e.keyCode === 13) {
sendLine();
}
};
startRaft({applyCmd: applyCmd});
flushSends();
}