-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
239 lines (219 loc) · 7.6 KB
/
index.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
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
// Initial setup for server
var http = require("http"),
express = require("express"),
bodyParser = require("body-parser"),
app = express(),
updateSpeed = 1000; // Calls the main update function this many milliseconds
// Loads index.html inside /client folder
app.use(express.static(__dirname + "/client"));
// Get body parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Start the server
http.createServer(app).listen(3000, function(){
console.log("Server running on port 3000");
});
var temp_id = 0;
// Database of all messages
// Add initial data to database
var database = new Object();
// Array to be referenced to of posts that have expired
// Elements are [posting, Date()]
var removeList = new Object();
// Creates a JSON object for each post
function posting(id, ttl, question, tags, comments){
"use strict";
// If no time stamp assigned to message, assign default ID (for initializing the server with data)
if (id === null){
id = temp_id;
temp_id++;
}
id = id.toString();
database[id] = {"id": id, "ttl": ttl * 1000, "question": question, "tags": tags, "comments": comments};
}
// Initialize server with data to simulate a database
posting(null, 10, "I'm trying to get my server running via node.js but it's not working. Any pointers?", ["node","server","computer science","programming","web"], []);
posting(null, 20, "What is meant by a handshaking protocol?", ["computer science", "networking"], ["A protocol uses handshaking if the two communicating entities first exchange control packets before sending data to each other.", "SMTP uses handshaking at the application layer whereas HTTP does not."]);
posting(null, 30, "HTTP response messages never have an empty message body. True or False?", ["computer science", "networking", "http"], ["this is false"]);
posting(null, 45, "What comes down but never goes up?", ["riddle", "misc"], ["the answer is rain"]);
posting(null, 60, "What has a foot but no legs?", ["riddle"], []);
posting(null, 75, "If the answer to life is 42, what is the question?", ["life"], []);
posting(null, 90, "What is your favorite thai restaurant?", ["food", "thai", "restaurant"], []);
posting(null, 150, "What information is used by a process running on one host to identify a process running on another host??", ["computer science", "networks"], ["The IP address of the destination host and the port number of the destination socket."]);
posting(null, 210, "Where are cheap places to take a date?", ["relationships", "food", "places"], []);
posting(null, 300, "Which Hawaii island should I go to?", ["travel", "places"], []);
posting(null, 600, "Do you know a good revolving sushi place?", ["food", "sushi"], []);
// A function that is called constantly by the server to reduce the postings' times by 'amount'
function updateTimes(amount){
"use strict";
Object.keys(database).forEach(function(e,i,a){
var post = database[e];
post.ttl -= amount;
if (post.ttl <= 0){
removeList[e] = new Date().getTime();
delete database[e];
}
});
}
// Checks postings if they need to be removed
function removeExpired(){
"use strict";
var limit = new Date().getTime();
Object.keys(removeList).forEach(function(e,i,a){
if (limit - removeList[e] > 30 * updateSpeed){
delete removeList[e];
}
});
}
// Call the function "updateDatabase" every X milliseconds
setInterval(function(){
updateTimes(updateSpeed);
}, updateSpeed);
// Clean up removeList so that it doesn't get backed up
setInterval(removeExpired, 30 * updateSpeed);
// Client is asking server if any posts have updated
// Client should send an array of message IDs
app.post("/update", function (req, res){
"use strict";
var updatedPosts = [];
var postIds = req.body["postids[]"];
// If the client has no posts, can't update anything
if (typeof postIds === "undefined"){
res.send("0");
return;
}
// For rare case where only one question exists on the client's page, postIds will return
// a standalone string. Convert this into an array so that we can use forEach on it.
if (postIds.constructor !== Array)
postIds = [postIds];
// Get array of posting IDs that the client has knowledge of and evaluate it
postIds.forEach(function(pid, index, array){
// If the client has this message, send it to be updated on client-side
if (database[pid] !== undefined){
updatedPosts.push(database[pid]);
}
});
// Return a JSON object of the available postings
res.json(updatedPosts);
});
// Client is asking server if any new posts have been added
app.post("/add", function (req, res){
"use strict";
var newPosts = {};
var keys = Object.keys(database);
// Get client data
var postIds = req.body["postids[]"];
var tag = req.body.tag;
// If the client has no posts
if (typeof postIds === "undefined"){
// If requesting a tag, send only messages that have the tag
if (tag !== ""){
for (var i = 0; i < keys.length; i++){
// Get message's tags
var tags = database[keys[i]].tags;
for (var j = 0; j < tags.length; j++){
// Tag is found, add to list and break the loop
if (tags[j] === tag){
newPosts[keys[i]] = database[keys[i]];
break;
}
}
}
} else { // No tag, so send the entire database
newPosts = database;
}
// Send the messages
res.json(newPosts);
return;
}
if (postIds.constructor !== Array)
postIds = [postIds];
// If requesting a tag, only get messages that have the tag
if (tag !== ""){
for (var i = 0; i < keys.length; i++){
// Message exists on client side, so skip it
var old = false;
for (var k = 0; k < postIds.length; k++){
// Client already has this message
if (postIds[k] === keys[i]){
old = true;
break;
}
}
if (old) continue;
// Check each tag
var tags = database[keys[i]].tags;
for (var j = 0; j < tags.length; j++){
// Found tag, add to list and break from loop
if (tags[j] === tag){
newPosts[keys[i]] = database[keys[i]];
break;
}
}
}
} else { // No tag, so check entire database
for (var i = 0; i < keys.length; i++){
// Message exists on client side, so skip it
var old = false;
for (var k = 0; k < postIds.length; k++){
// Client already has this message
if (postIds[k] === keys[i]){
old = true;
break;
}
}
if (!old)
newPosts[keys[i]] = database[keys[i]];
}
}
// Return remaining posts back to the client
res.json(newPosts);
});
// Client is asking server if any posts have expired
// Returns array of message IDs that have expired
app.post("/remove", function (req, res){
"use strict";
var results = [];
// Get message IDs and put them in array
Object.keys(removeList).forEach(function(e, i, a){
results.push(e);
});
res.json(results);
});
// When the user submits a new question
app.post("/question", function(req,res){
"use strict";
var message = req.body.message;
// Check that message is 12 characters
if (message === "undefined" || message.length < 12){
res.json(-1);
return;
}
var tags = req.body.tags;
// Check that there is at least one tag
if (tags === "undefined"){
res.json(-2);
return;
}
tags = tags.split(" "); // Puts tags into an array
var ttl = JSON.parse(req.body.ttl);
// Add message to database get seconds
posting(new Date().getTime(), ttl * 60, message, tags, []);
res.json(0);
});
// When the user submits an answer to a question
app.post("/answer", function(req,res){
"use strict";
var id = JSON.parse(req.body.id);
var message = req.body.message;
// Check if answer is long enough
if (message === "undefined" || message.length < 12){
res.json(-1);
return;
}
database[id].comments.push(message);
if (database[id].ttl < 60000){
database[id].ttl = 60000;
}
res.json(0);
});