Location based real time online posts system
- Get user's location with HTML5 geolocation api and display it the google map.
- Customized the loading screen to compensate the delay generated by geolocation api and google map.
- Implement a server side session mechanism by saving session id in cookie
- Implement persistent storage for sessions
Initialize and retrieve session on every request
his.initSession = function (success) {
let cookies = cookie.parse(this.req.headers.cookie || '');
if (!cookies || !cookies['sessionId']) {
this.res.setHeader('Set-Cookie', cookie.serialize('sessionId',
uuidV4(),
{
'maxAge': this.maxAge
}));
success();
} else {
this.sessionId = cookies['sessionId'];
session.find(this.sessionId).then((session) => {
this.session = session;
success();
}, () => {
this.session = {};
success();
});
}
};
Save session into persistent storage on every request finished.
this.saveSession = function () {
if (this.sessionId)
session.save(this.sessionId, this.session);
this.sessionId = null;
this.session = {};
};
Invoke session init and saving in router
if (r.length > 0) {
var action = r[0][2];
var arr = action.split('#');
let Ctrl = config.controllers[arr[0]];
controller = new Ctrl();
getParams(req, rUrl, r).then(function (params) {
controller.setParams(params);
controller.setReqRes(req, res);
controller.setView(arr[0] + '/' + arr[1]);
controller.initSession(() => {
if (controller[arr[1]]) {
controller[arr[1]].call(controller);
if (controller.sync) controller.respond(200);
}
else {
res.writeHead(404, {'Content-type': 'text/html'});
res.end('Action not found', 'utf-8')
}
});
});
} else {
let Ctrl = config.controllers['file'];
controller = new Ctrl();
getParams(req, rUrl).then(function (params) {
controller.setParams(params);
controller.setReqRes(req, res);
controller.setPathname(rUrl.pathname);
controller.initSession(() => {
const paths = rUrl.pathname.substring(1).split('/');
const filename = paths[paths.length - 1];
const extension = filename.substring(filename.indexOf('.') + 1);
if (controller[extension]) controller[extension].call(controller);
else {
res.writeHead(404, {'Content-type': 'text/html'});
res.end('Resource not found', 'utf-8')
}
});
});
Generate random user if its the first time they visit the site
function randomUserId(length) {
let alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let result = [];
for (let i = 0; i < length; i++)
result.push(alphabet.charAt([random(0, alphabet.length)]))
return result.join('');
}
Create a post and push it to client through websocket
let userId = this.session["userId"];
if (!userId)
userId = randomUserId(15);
this.session["userId"] = userId;
this.variables['userId'] = userId;
user.find(userId).then((user) => {
sendPosts(this, user);
}, () => {
let u = {"avatar": {"icon": randomIcon(), 'theme': randomTheme()}};
user.add(userId, u).then(() => {
sendPosts(this, u);
})
});
function sendPosts(self, u) {
self.variables['user'] = u;
post.findAllWithUsers()
.then((posts) => {
self.variables['posts'] = posts.sort((p1, p2) => p2.timestamp - p1.timestamp);
self.respond(200);
});
}
Create post on client side
let formData = {};
formData['post[latitude]'] = pos.lat;
formData['post[longitude]'] = pos.lng;
formData['post[message]'] = messageTextarea.value;
let body = Object.keys(formData).map(function (key) {
return key + '=' + formData[key];
}).join('&');
ajax('post', 'POST', body, 'application/json')
.then(function () {
messageTextarea.value = '';
});