Skip to content
CSS JavaScript HTML
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
app
configs
data
libs
public
.gitignore
Procfile
README.md
package.json
server.js

README.md

Posts

Location based real time online posts system

Features

  • 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

Implementation

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 = '';
        });
You can’t perform that action at this time.