http://jxck.node-ninja.com

about SlideStream

& Tips for Realtime Web App

This slide is Best optimized for Chrome & FireFox

should use them ;)

Jack

about me

Jxck

Todays Goal

SlideStream

What is SlideStream ?

Realtime Streambased Slide Tool

Sync Slide Paging

Sync Slide Paging

Authentication/Authorization

// 1. Authentication in Express
app.post('/admin', function(req, res) {
  req.session.admin = false;
  if (req.body.user === config.secret.user &&
      pass(req.body.pass) === config.secret.pass) {
    req.session.admin = true;
  }
  res.redirect('/nodefest2011.html');
});
// 2. Sharing session btw Express & Socket.IO
io.set('authorization', function(handshakeData, callback) {
  if (handshakeData.headers.cookie) {
    var cookie = handshakeData.headers.cookie;
    var sessionID = parseCookie(cookie)['connect.sid'];
    // check the express session store
    sessionStore.get(sessionID, function(err, session) {
      if (err) {
        // not found
        callback(err.message, false);
      } else {
        // found
        handshakeData.session = session;
        callback(null, true);
      }
    });
  } else {
    return callback(null, true);
    // socket.io-client from node process dosen't has cookie
    // return callback('Cookie dosen\'t found', false);
  }
});
  
// 3. Authorization in Socket.IO checking handshake data
// move slide only by admin
socket.on('go', function(to) {
  if (!socket.handshake.session) return false;
  if (!socket.handshake.session.admin) return false;
  socket.broadcast.emit('go', to);
});

practice

Security Hole in crossdomain app

// lazy broadcasting server
socket.on('review', function(data) {
  socket.volatile.emit('review', data);
  socket.volatile.broadcast.emit('review', data);
});
// client
socket.on('review', function(data) {
  var $li = $('<li>').text(data);
  $('#review').append($li);
});
// you can send dirty data to every client
// from your console
var socket = io.connect(/* path to server */);
socket.emit('review', 'm@(^_^) pugya~~~');

Steal the TTY

all what I want is..

tty.png

But, It has a lot of problem

If I steal that & broadcast input, then...

Consider another way..

How to display console ?

Readline is standard module

Search usecase of tty, and found this

console image

fake prompt with require('readline')

var readline = require('readline').createInterface(process.stdin, process.stdout);
 ,  spawn = require('child_process').spawn,
 ,  socket = require('socket.io-client')
 ,  worker = null
 ;
rl.on('line', function(line) {
  var lines = line.split(' ');
  var command = lines.shift();
  worker = spawn(command, lines);

  worker.stdout.on('data', function(rawdata) {
    console.log(data); // print to shell
    socket.emit('line', data + '\n'); // send to socketserver
  });
});
rl.setPrompt(prefix, prefix.length);
rl.prompt();

How to display Editor ?

Steal the tty needs client side Emacs

get a output of emacs needs emacs

Don't do that with Node, Yes Emacs

(require 'auto-save-buffers)
(run-with-idle-timer 0.1 t 'auto-save-buffers)

fs.watchFile() is too slow for realtime

load file again and again :P

function CodeStream(file) { // Not a real Stream !!
  this.file = file;
  this.cache = '';
  events.EventEmitter.call(this);
  this.readCode();
}

util.inherits(CodeStream, events.EventEmitter);

CodeStream.prototype.readCode = function() {
  fs.readFile(this.file, 'utf8', function(err, data) {
    if (err) {
      return console.error(err);
    }
    if (data !== this.cache) {
      this.emit('code', data);
      this.cache = data;
    }
    setTimeout(function() {
      this.readCode();
    }.bind(this), 500);
  }.bind(this));
};

practice

matter btwn Diff & volatile

volatile sends without ACK

    // expected
    bar
  
    // actual
    foo
    bar

but we need volatile in realtime world

see more about volatile is here

practice

simple is best

bottole neck

At first, my slide was Crazy Heavy

don't know what's wrong ..

but they seems fine..

Syntacs Higlight

sh.js

Domein Specific minimal logic

(not stable, adding incrementaly..)

render.prototype.higlightJS = function() {
  this.cache = this.cache
    .replace(//g, '>')
    .replace(/"(.*?)"/g, '\"$1\"')
    .replace(/'(.*?)'/g, '\'$1\'')
    .replace(/(var|function|static|true|false)/g, '$1')
    .replace(/([A-Za-z0-9]*?)\(/g, '$1(')
    .replace(/^\/\/(.*)/g, '//$1')
    .replace(/[^:]\/\/(.*)/g, '//$1')
    .replace(/\/\*\*(.*)/g, '/**$1')
    .replace(/\*(.*)/g, '* $1')
    .replace(/(\d{2,4}?)/g, '$1')
    ;
};

render.prototype.higlightBash = function() {
  this.cache = this.cache
    .replace(/(ls|cd|tree|rm|\sexpress\s|npm|\snode\s)/g, '$1')
    .replace(/(create)/g, '$1')
    .replace(/(Jxck\$)/g, '$1')
    .replace(/(\d{4}?)/g, '$1')
    ;
};

practice

very important poin in Node.js & Realtime scene

stress test

With Nodejs_jp & all of First Server

stress test

stream base app

stream is interface on data flow

anyone.on
('uncaughtQuestion?');

May the Node be with you

Jxck.on('end');

// thank you ;)

/ (0)