SlideShare a Scribd company logo
SocketStream
A web framework for
single page apps
Created by
Owen Barnes
@temporalwave
!
!

(my boss at a former company)
About me
Paul Jensen
@paulbjensen
!
!

(I’m the new lead developer)
Where to begin?
Why Single Page
Apps?
With a traditional web app,
the user has to refresh the
page to see new information
Client

Server

Time
GET/football/live

Client

Server

Time

HTTP/1.1
HTTP/1.1 200 OK

Client

Server

Time
20 seconds later…

Client

Server

Time
I wonder what the latest score is…
Let’s reload the page

Client

Server

Time
GET/football/live

Client

Server

Time

HTTP/1.1
HTTP/1.1 304 Not Modified

Client

Server

Time
Client

Server

Time
The user had to press F5
to get at any new information
Client

Server

Time
Client

Server

Time

Even though there was
no new information,
the server still had to serve
the HTTP request
This is not a fun experience
How do we make this
better?
Client

Server

Time
We could use AJAX to
update the page
We’d save the user
having to press the F5 key
What else can we do?
Client

Server

Time
Optimise the response
GZIP the response
data, and …
Avoid sending data we
already have on the client
We could also
separate the HTML
from the data
Reuse the HTML on
the client
…and use the server to
provide you with just
data
And the web site becomes a
client

Web App

Native App

Server

API User
The server is just an API
A beautiful separation
of concerns
Overview
•

The server becomes a REST API serving JSON

•

HTML compilation is done on the client

•

As a result, less processing & bandwidth is
consumed by the server
Why Realtime?
Client

Server

Time
Polling the server every
[n] seconds for new
data is redundant
There has to be a
better way
What if the server could
send its client(s) new
data as soon as it came
about?
We can, thanks to
WebSockets
WebSockets allows data
to be sent both ways
Client

Server

Time
Client

Server

Time

Goal
The server sends a message
to the client that an action has
occurred

Client

Server

Time

Goal
We eliminate the need
to poll the server for
new data
Overview
•

We can replace AJAX polling with WebSockets,
and provide a better user experience as a result

•

We also remove the need to make redundant
polling requests back to the server.

•

We use WebSockets for sending/receiving JSON
Single Page Apps
+
The Realtime Web
There are many ways
to build this kind of
app
You could build it
mostly from scratch, and
use Express + Socket.io
Or alternatively, you
could use a web
framework like Meteor
or Firebase
SocketStream is
somewhere in-between
these 2 approaches
It provides tools to help
with building realtime
single page apps...
... Whilst trying not to
restrict what
technologies you can
use with your app
For example, we don't
provide an ORM.
Instead, you choose the
database & the ORM
Also, we don't mandate using a
specific client-side framework
!

You can use BackBone, Angular,
Ember, or something else, that is
entirely your choice.
What we focus on
instead are these
things:
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
I'll run through each of
these, 1-by-1. But first,
let's look at how to use
SocketStream
Getting started

npm install -g socketstream
!

socketstream new my_app
Getting started
!

!
!
!

Success! Created app 'my_app' with:
✓ Basic chat demo (-m for minimal install)
✓ Javascript example code (-c if you prefer CoffeeScript)
✓ Plain HTML for views (-j if you prefer Jade)
Next, run the following commands:
cd my_app
[sudo] npm install
To start your app:
node app.js

Here's what the initial file/
folder structure looks like
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
Client code is organised
into 5 sub-folders
Client side code organisation
•

CODE stores client side JavaScript files and libraries

•

CSS stores CSS files

•

STATIC stores public files like images, font files, and other
assets

•

TEMPLATES stores HTML templates for the single page
app to render on the client

•

VIEWS stores HTML files that are rendered from the server
for the initial page
Those sub-folders have subfolders, but are optional
This is how we load them
// My SocketStream 0.3 app

!

var http = require('http'),
ss = require('socketstream');

!

// Define a single-page client called 'main'
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});

!

// Serve this client on the root URL
ss.http.route('/', function(req, res){
res.serveClient('main');
});
// My SocketStream 0.3 app

!

var http = require('http'),
ss = require('socketstream');

!

// Define a single-page client called 'main'
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});

!

// Serve this client on the root URL
ss.http.route('/', function(req, res){
res.serveClient('main');
});
// My SocketStream 0.3 app

!

var http = require('http'),
ss = require('socketstream');

!

// Define a single-page client called 'main'
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});

!

// Serve this client on the root URL
ss.http.route('/', function(req, res){
res.serveClient('main');
});
// My SocketStream 0.3 app

!

var http = require('http'),
ss = require('socketstream');

!

// Define a single-page client called 'main'
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});

!

// Serve this client on the root URL
ss.http.route('/', function(req, res){
res.serveClient('main');
});
// My SocketStream 0.3 app

!

var http = require('http'),
ss = require('socketstream');

!

// Define a single-page client called 'main'
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});

!

// Serve this client on the root URL
ss.http.route('/', function(req, res){
res.serveClient('main');
});
// My SocketStream 0.3 app

!

var http = require('http'),
ss = require('socketstream');

!

// Define a single-page client called 'main'
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});

!

// Serve this client on the root URL
ss.http.route('/', function(req, res){
res.serveClient('main');
});
// My SocketStream 0.3 app

!

var http = require('http'),
ss = require('socketstream');

!

// Define a single-page client called 'main'
ss.client.define('main', {
view: 'app.html',
css: ['libs/reset.css', 'app.styl'],
code: ['libs/jquery.min.js', 'app'],
tmpl: '*'
});

!

// Serve this client on the root URL
ss.http.route('/', function(req, res){
res.serveClient('main');
});
SocketStream uses
Browserify to handle
requiring JS files
Browserify allows us to
use a Node.js style of
requiring JS files
// This file automatically gets called first by
SocketStream and must always exist

!

// Make 'ss' available to all modules and the
browser console
window.ss = require('socketstream');

!

ss.server.on('disconnect', function(){
console.log('Connection down :-(');
});

!

ss.server.on('reconnect', function(){
console.log('Connection back up :-)');
});

!

ss.server.on('ready', function(){

!

!
!

// Wait for the DOM to finish loading
jQuery(function(){
// Load app
require('/app');
});

});
// This file automatically gets called first by
SocketStream and must always exist

!

// Make 'ss' available to all modules and the
browser console
window.ss = require('socketstream');

!

ss.server.on('disconnect', function(){
console.log('Connection down :-(');
});

!

ss.server.on('reconnect', function(){
console.log('Connection back up :-)');
});

!

ss.server.on('ready', function(){

!

!
!

// Wait for the DOM to finish loading
jQuery(function(){
// Load app
require('/app');
});

});
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
Over the years, developers
have come up with new
languages to generate
HTML, CSS, and JavaScript
SocketStream allows
developers to use these
code preprocessors in
their apps
Adding a preprocessor is simple

// Code Formatters
ss.client.formatters.add(require('ss-stylus'));
For Javascript

•

SS-COFFEE - supports using CoffeeScript

•

SS-GORILLA - supports using GorillaScript
For CSS

•

SS-STYLUS - supports using Stylus

•

SS-LESS - supports using Less
For HTML Views

•

SS-JADE - supports using Jade
For HTML Templating

•

SS-HOGAN - supports using Twitter's Hogan.js

•

SS-COFFEEKUP - supports using CoffeeKup
Setting a Templating engine

// Use server-side compiled Hogan (Mustache)
templates. Others engines available
ss.client.templateEngine.use(require('ss-hogan'));
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
Having to press F5 to reload
the page in order to view
changes to HTML/CSS/JS...
... is not a fun experience
In development mode,
SocketStream will watch the
client files for changes, and
reload the page when they
occur
In the case of CSS,
SocketStream will apply
the changes without
reloading the page
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
Client-side HTML
templates are made
available to the browser
via the ss.tmpl object
SocketStream
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
When you're building a
single page app, you'll
have a lot of JS files, and
maybe a few CSS files
But serving a HTML
page with lots of these
files can take time, and
is inefficient
SocketStream provides a
way to concatenate, minify,
and GZip these files into 1
JS and 1 CSS file
This saves bytes being
transferred, as well as
reducing the number of
HTTP requests you make
Also, you can tell
SocketStream to load
these files from a CDN
Setting a Templating engine

// Minimize and pack assets if you type: SS_ENV=production node app.js
if (ss.env === 'production') ss.client.packAssets();
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
Web Workers are handy
for intensive client-side
JS operations
SocketStream provides
support for using Web
Workers in your app
First, create a folder
Next, put your web worker files in
that folder
Then, load the worker in a client
code file, and enjoy
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
SocketStream uses
Connect middleware to
support HTTP features
SocketStream uses the following
middleware by default:
•

compress - for GZipping assets

•

cookieParser - for handling user tracking

•

favicon - for serving a favicon.ico file

•

session - for handling sessions

•

static - for serving static assets
SocketStream uses the following
middleware by default:
•

compress middleware is loaded first, before all
other middleware

•

static middleware is loaded last, after all other
middleware
SocketStream provides
a way to load custom
middleware into the
connect stack
ss.http.middleware.prepend()
ss.http.middleware.append()
This allows you to use all
of the connect
middleware out there
today, i.e. EveryAuth
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
We use connect’s session
middleware, so authentication
can be done with either
EveryAuth, PassportJS, or you
can roll your own.
We also recommend
using connect-redis
Both HTTP and
WebSocket interfaces
can get/set the session
data
Via HTTP
// app.js
ss.http.router.on('/updateSession', function(req, res) {
req.session.myVar = 4321;
res.end('req.session.myVar has been updated to', req.session.myVar);
});
Via WebSockets
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
RPC is a common
pattern for clients
requesting data from
the server
SocketStream provides
a way to construct RPC
APIs with flexibility
SocketStream
SocketStream
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
PubSub is a great
pattern for Single Page
Apps
SocketStream handles
this in various ways:
1 - Publishing to everyone
viewing the app right now
Server
ss.publish.all('newMessage', message);

// Broadcast the message to everyone

Client
// Listen out for newMessage events coming from the server
ss.event.on('newMessage', function(message) {
// do something with the message
});
2 - Sending to private channels
Server (subscribe/unsubscribe the session )
// in a /server/rpc file after calling req.use('session') middleware

!

req.session.channel.subscribe('disney')

!

req.session.channel.unsubscribe('kids')

!

req.session.channel.reset()

// unsubscribes the session from every channel

req.session.channel.list()

// shows what channels are subscribed to

!
2 - Sending to private channels
Server (publish to channel)
// in a /server/rpc file
ss.publish.channel('disney', 'chatMessage', {from: 'jerry', message: 'Has anyone seen
Tom?'});

Client (receive channel message)
// in a /client/code file
ss.event.on('chatMessage', function(msg, channelName){
console.log('The following message was sent to the ' + channelName + ' channel:', msg);
});
3 - Sending to users
Server
// in a /server/rpc file
ss.publish.user('fred', 'specialOffer', 'Here is a special offer just for you!');
4 - Sending to a browser
tab
Server
// in a /server/rpc file
ss.publish.socketId('254987654324567', 'justForMe', 'Just for one tab');
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
On top of RPC and PubSub,
SocketStream provides you
with a way to create custom
request responders
Request Response is
basically a WebSocket
message handler
It allows you to write
message handling for
games, where every
byte matters
HTML / CSS / JS
code preprocessing

Minifying CSS/JS for
production use

Client-side code
organisation

HTML Templates

WebSocket
Management

Live Reload

Building RPC APIs

Building PubSub APIs

Session Management

Building custom APIs
on top of WS

Web Workers

Connect middleware
compatibility
WebSockets are not
immortal…
They are mangled by
mobile networks…
Blocked by firewalls…
Routed to dead ends by
proxy servers
And severed by train
tunnels
Also, browser support
for WebSockets isn’t
guaranteed
You need a transport
strategy
Originally, SocketStream
used Socket.io
But Socket.io asserted
that if a browser
supported WebSockets,
then it would work
They learned from this,
by building Engine.io
I created the transport
wrapper for Engine.io in
SocketStream for
Bechtel & Dashku
And designed it to
reconnect the client
when severed
Months later, it made it’s
way into SocketStream’s
core.
SocketStream let’s you
use this, alongside
SockJS
…and that is
SocketStream in a
nutshell. Whew!
Let’s look at some
SocketStream apps in
the wild
Hollow
hollowdocumentary.com
Vmux
vmux.co
Dashku
dashku.com
SocketStream plugins
SS-BACKBONE
SS-ANGULAR
SS-CUCUMBER
Tips for deploying
SocketStream in
production
1 - Check your server’s
ulimit configuration
(This can bite you hard)
I learned this when Dashku went
#1 on Hacker News in 45min
2 - Use HTTPS, but
handle it at the load
balancer level rather
than at the app level
HTTPS helps to improve
the stability of WebSocket
connections, especially
on mobile devices
But Node’s HTTPS
implementation is
noticeably slower than
using HAProxy or Nginx
Where is SocketStream
going next?
We’re in the process of
getting SocketStream’s
test coverage up
We’re also trying to
close some ancient
bugs
We also need better
documentation
We’re giving the web
site an overhaul
And we want to
document how
SocketStream’s internals
function, to help build 0.4
but what about 0.4?
…0.4 is starting to look like these:
I promise you all, it’s
coming in June 2014
Thank You

More Related Content

KEY
Mobile HTML, CSS, and JavaScript
PDF
jQuery Proven Performance Tips & Tricks
PDF
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
PDF
High Performance JavaScript - WebDirections USA 2010
PDF
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
PDF
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
PPTX
Don't Over-React - just use Vue!
PPTX
Nodejs.meetup
Mobile HTML, CSS, and JavaScript
jQuery Proven Performance Tips & Tricks
Cool like a Frontend Developer: Grunt, RequireJS, Bower and other Tools
High Performance JavaScript - WebDirections USA 2010
Optimising Your Front End Workflow With Symfony, Twig, Bower and Gulp
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Don't Over-React - just use Vue!
Nodejs.meetup

What's hot (20)

PPT
WordPress and Ajax
PDF
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao Paulo
PDF
Mastering Grunt
PDF
Developing for Mobile
PDF
Instant and offline apps with Service Worker
PDF
Meetup Performance
KEY
#NewMeetup Performance
PPTX
JavaScript performance patterns
PPTX
JavaScript Performance Patterns
PPTX
High Performance Social Plugins
PDF
High Performance JavaScript (Amazon DevCon 2011)
KEY
Writing your Third Plugin
PDF
Progressive Enhancement 2.0 (Conference Agnostic)
PDF
jQuery UI and Plugins
PPTX
HTML5 Web Workers-unleashed
PPTX
Enough with the JavaScript already!
PDF
Learning from the Best jQuery Plugins
PPTX
Liking performance
PPTX
Building a PWA - For Everyone Who Is Scared To
PDF
Building an HTML5 Video Player
WordPress and Ajax
HTML5, The Open Web, and what it means for you - MDN Hack Day, Sao Paulo
Mastering Grunt
Developing for Mobile
Instant and offline apps with Service Worker
Meetup Performance
#NewMeetup Performance
JavaScript performance patterns
JavaScript Performance Patterns
High Performance Social Plugins
High Performance JavaScript (Amazon DevCon 2011)
Writing your Third Plugin
Progressive Enhancement 2.0 (Conference Agnostic)
jQuery UI and Plugins
HTML5 Web Workers-unleashed
Enough with the JavaScript already!
Learning from the Best jQuery Plugins
Liking performance
Building a PWA - For Everyone Who Is Scared To
Building an HTML5 Video Player
Ad

Viewers also liked (20)

PDF
Web Crawling with NodeJS
ODP
Lambda Architecture with Spark
PPTX
Test in action – week 1
PPT
Ese Neno Da Rua
PPT
Aspen Lion
PPT
Segundo Caraujulca Galvez
KEY
Springbreak Workshop
PDF
Who Is Muhammad (Pbuh)
PPTX
Proyek penciptaan dan digitalisasi konten
PPTX
Lontar class 2
PPTX
Lesson16vocab
PDF
洋服はあなたの良さを引き立てるコミュニケーション
PDF
Proposal Bebaskan Pengetahuan 2014
PPTX
DoInk2'
PPTX
how to get a job in advertising
PPT
Presentatie ExcellentSecretary
PPT
QUESTION 7
PPT
State and Capital Game
PPTX
Kelas lontar 1
PPTX
Vocab lesson 11
Web Crawling with NodeJS
Lambda Architecture with Spark
Test in action – week 1
Ese Neno Da Rua
Aspen Lion
Segundo Caraujulca Galvez
Springbreak Workshop
Who Is Muhammad (Pbuh)
Proyek penciptaan dan digitalisasi konten
Lontar class 2
Lesson16vocab
洋服はあなたの良さを引き立てるコミュニケーション
Proposal Bebaskan Pengetahuan 2014
DoInk2'
how to get a job in advertising
Presentatie ExcellentSecretary
QUESTION 7
State and Capital Game
Kelas lontar 1
Vocab lesson 11
Ad

Similar to SocketStream (20)

PDF
Real-Time with Flowdock
PDF
Real time web apps
KEY
20120306 dublin js
PPTX
Mobile gotcha
KEY
Realtime rocks
KEY
20120802 timisoara
PPTX
VisualWeb - Building a NodeJS Server Meshwork and Full-Javascript Stack Frame...
PPTX
Building and Scaling Node.js Applications
PDF
Building Killer RESTful APIs with NodeJs
PDF
Real Time Web with Node
KEY
Jugando con websockets en nodeJS
PDF
Comet with node.js and V8
PPTX
Training Webinar: Enterprise application performance with server push technol...
PDF
Building real time applications with Symfony2
PDF
Nodejs + Rails
PPT
Node js
PPTX
Hangouts in 30 minutes Socket.io
PDF
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
KEY
Socket applications
PDF
soft-shake.ch - Hands on Node.js
Real-Time with Flowdock
Real time web apps
20120306 dublin js
Mobile gotcha
Realtime rocks
20120802 timisoara
VisualWeb - Building a NodeJS Server Meshwork and Full-Javascript Stack Frame...
Building and Scaling Node.js Applications
Building Killer RESTful APIs with NodeJs
Real Time Web with Node
Jugando con websockets en nodeJS
Comet with node.js and V8
Training Webinar: Enterprise application performance with server push technol...
Building real time applications with Symfony2
Nodejs + Rails
Node js
Hangouts in 30 minutes Socket.io
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
Socket applications
soft-shake.ch - Hands on Node.js

More from Paul Jensen (6)

PDF
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
PDF
Objection.js, a SQL ORM
PDF
E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
PPTX
Lnug jan 2018
PDF
Desktop apps with node webkit
PDF
Geokit In Social Apps
End to end testing Single Page Apps & APIs with Cucumber.js and Puppeteer (Em...
Objection.js, a SQL ORM
E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer
Lnug jan 2018
Desktop apps with node webkit
Geokit In Social Apps

Recently uploaded (20)

PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
MYSQL Presentation for SQL database connectivity
PDF
cuic standard and advanced reporting.pdf
PDF
Modernizing your data center with Dell and AMD
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
Cloud computing and distributed systems.
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Big Data Technologies - Introduction.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Understanding_Digital_Forensics_Presentation.pptx
20250228 LYD VKU AI Blended-Learning.pptx
Chapter 3 Spatial Domain Image Processing.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Network Security Unit 5.pdf for BCA BBA.
MYSQL Presentation for SQL database connectivity
cuic standard and advanced reporting.pdf
Modernizing your data center with Dell and AMD
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Cloud computing and distributed systems.
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Machine learning based COVID-19 study performance prediction
Big Data Technologies - Introduction.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Digital-Transformation-Roadmap-for-Companies.pptx
Review of recent advances in non-invasive hemoglobin estimation
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...

SocketStream

  • 2. A web framework for single page apps
  • 7. With a traditional web app, the user has to refresh the page to see new information
  • 12. I wonder what the latest score is… Let’s reload the page Client Server Time
  • 14. HTTP/1.1 304 Not Modified Client Server Time
  • 16. The user had to press F5 to get at any new information Client Server Time
  • 17. Client Server Time Even though there was no new information, the server still had to serve the HTTP request
  • 18. This is not a fun experience
  • 19. How do we make this better?
  • 21. We could use AJAX to update the page
  • 22. We’d save the user having to press the F5 key
  • 23. What else can we do?
  • 27. Avoid sending data we already have on the client
  • 28. We could also separate the HTML from the data
  • 29. Reuse the HTML on the client
  • 30. …and use the server to provide you with just data
  • 31. And the web site becomes a client Web App Native App Server API User
  • 32. The server is just an API
  • 34. Overview • The server becomes a REST API serving JSON • HTML compilation is done on the client • As a result, less processing & bandwidth is consumed by the server
  • 37. Polling the server every [n] seconds for new data is redundant
  • 38. There has to be a better way
  • 39. What if the server could send its client(s) new data as soon as it came about?
  • 40. We can, thanks to WebSockets
  • 41. WebSockets allows data to be sent both ways
  • 44. The server sends a message to the client that an action has occurred Client Server Time Goal
  • 45. We eliminate the need to poll the server for new data
  • 46. Overview • We can replace AJAX polling with WebSockets, and provide a better user experience as a result • We also remove the need to make redundant polling requests back to the server. • We use WebSockets for sending/receiving JSON
  • 47. Single Page Apps + The Realtime Web
  • 48. There are many ways to build this kind of app
  • 49. You could build it mostly from scratch, and use Express + Socket.io
  • 50. Or alternatively, you could use a web framework like Meteor or Firebase
  • 52. It provides tools to help with building realtime single page apps...
  • 53. ... Whilst trying not to restrict what technologies you can use with your app
  • 54. For example, we don't provide an ORM. Instead, you choose the database & the ORM
  • 55. Also, we don't mandate using a specific client-side framework ! You can use BackBone, Angular, Ember, or something else, that is entirely your choice.
  • 56. What we focus on instead are these things:
  • 57. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 58. I'll run through each of these, 1-by-1. But first, let's look at how to use SocketStream
  • 59. Getting started npm install -g socketstream ! socketstream new my_app
  • 60. Getting started ! ! ! ! Success! Created app 'my_app' with: ✓ Basic chat demo (-m for minimal install) ✓ Javascript example code (-c if you prefer CoffeeScript) ✓ Plain HTML for views (-j if you prefer Jade) Next, run the following commands: cd my_app [sudo] npm install To start your app: node app.js

  • 61. Here's what the initial file/ folder structure looks like
  • 62. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 63. Client code is organised into 5 sub-folders
  • 64. Client side code organisation • CODE stores client side JavaScript files and libraries • CSS stores CSS files • STATIC stores public files like images, font files, and other assets • TEMPLATES stores HTML templates for the single page app to render on the client • VIEWS stores HTML files that are rendered from the server for the initial page
  • 65. Those sub-folders have subfolders, but are optional
  • 66. This is how we load them // My SocketStream 0.3 app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  • 67. // My SocketStream 0.3 app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  • 68. // My SocketStream 0.3 app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  • 69. // My SocketStream 0.3 app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  • 70. // My SocketStream 0.3 app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  • 71. // My SocketStream 0.3 app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  • 72. // My SocketStream 0.3 app ! var http = require('http'), ss = require('socketstream'); ! // Define a single-page client called 'main' ss.client.define('main', { view: 'app.html', css: ['libs/reset.css', 'app.styl'], code: ['libs/jquery.min.js', 'app'], tmpl: '*' }); ! // Serve this client on the root URL ss.http.route('/', function(req, res){ res.serveClient('main'); });
  • 73. SocketStream uses Browserify to handle requiring JS files
  • 74. Browserify allows us to use a Node.js style of requiring JS files
  • 75. // This file automatically gets called first by SocketStream and must always exist ! // Make 'ss' available to all modules and the browser console window.ss = require('socketstream'); ! ss.server.on('disconnect', function(){ console.log('Connection down :-('); }); ! ss.server.on('reconnect', function(){ console.log('Connection back up :-)'); }); ! ss.server.on('ready', function(){ ! ! ! // Wait for the DOM to finish loading jQuery(function(){ // Load app require('/app'); }); });
  • 76. // This file automatically gets called first by SocketStream and must always exist ! // Make 'ss' available to all modules and the browser console window.ss = require('socketstream'); ! ss.server.on('disconnect', function(){ console.log('Connection down :-('); }); ! ss.server.on('reconnect', function(){ console.log('Connection back up :-)'); }); ! ss.server.on('ready', function(){ ! ! ! // Wait for the DOM to finish loading jQuery(function(){ // Load app require('/app'); }); });
  • 77. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 78. Over the years, developers have come up with new languages to generate HTML, CSS, and JavaScript
  • 79. SocketStream allows developers to use these code preprocessors in their apps
  • 80. Adding a preprocessor is simple // Code Formatters ss.client.formatters.add(require('ss-stylus'));
  • 81. For Javascript • SS-COFFEE - supports using CoffeeScript • SS-GORILLA - supports using GorillaScript
  • 82. For CSS • SS-STYLUS - supports using Stylus • SS-LESS - supports using Less
  • 83. For HTML Views • SS-JADE - supports using Jade
  • 84. For HTML Templating • SS-HOGAN - supports using Twitter's Hogan.js • SS-COFFEEKUP - supports using CoffeeKup
  • 85. Setting a Templating engine // Use server-side compiled Hogan (Mustache) templates. Others engines available ss.client.templateEngine.use(require('ss-hogan'));
  • 86. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 87. Having to press F5 to reload the page in order to view changes to HTML/CSS/JS...
  • 88. ... is not a fun experience
  • 89. In development mode, SocketStream will watch the client files for changes, and reload the page when they occur
  • 90. In the case of CSS, SocketStream will apply the changes without reloading the page
  • 91. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 92. Client-side HTML templates are made available to the browser via the ss.tmpl object
  • 94. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 95. When you're building a single page app, you'll have a lot of JS files, and maybe a few CSS files
  • 96. But serving a HTML page with lots of these files can take time, and is inefficient
  • 97. SocketStream provides a way to concatenate, minify, and GZip these files into 1 JS and 1 CSS file
  • 98. This saves bytes being transferred, as well as reducing the number of HTTP requests you make
  • 99. Also, you can tell SocketStream to load these files from a CDN
  • 100. Setting a Templating engine // Minimize and pack assets if you type: SS_ENV=production node app.js if (ss.env === 'production') ss.client.packAssets();
  • 101. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 102. Web Workers are handy for intensive client-side JS operations
  • 103. SocketStream provides support for using Web Workers in your app
  • 104. First, create a folder
  • 105. Next, put your web worker files in that folder
  • 106. Then, load the worker in a client code file, and enjoy
  • 107. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 108. SocketStream uses Connect middleware to support HTTP features
  • 109. SocketStream uses the following middleware by default: • compress - for GZipping assets • cookieParser - for handling user tracking • favicon - for serving a favicon.ico file • session - for handling sessions • static - for serving static assets
  • 110. SocketStream uses the following middleware by default: • compress middleware is loaded first, before all other middleware • static middleware is loaded last, after all other middleware
  • 111. SocketStream provides a way to load custom middleware into the connect stack
  • 113. This allows you to use all of the connect middleware out there today, i.e. EveryAuth
  • 114. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 115. We use connect’s session middleware, so authentication can be done with either EveryAuth, PassportJS, or you can roll your own.
  • 116. We also recommend using connect-redis
  • 117. Both HTTP and WebSocket interfaces can get/set the session data
  • 118. Via HTTP // app.js ss.http.router.on('/updateSession', function(req, res) { req.session.myVar = 4321; res.end('req.session.myVar has been updated to', req.session.myVar); });
  • 120. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 121. RPC is a common pattern for clients requesting data from the server
  • 122. SocketStream provides a way to construct RPC APIs with flexibility
  • 125. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 126. PubSub is a great pattern for Single Page Apps
  • 128. 1 - Publishing to everyone viewing the app right now Server ss.publish.all('newMessage', message); // Broadcast the message to everyone Client // Listen out for newMessage events coming from the server ss.event.on('newMessage', function(message) { // do something with the message });
  • 129. 2 - Sending to private channels Server (subscribe/unsubscribe the session ) // in a /server/rpc file after calling req.use('session') middleware ! req.session.channel.subscribe('disney') ! req.session.channel.unsubscribe('kids') ! req.session.channel.reset() // unsubscribes the session from every channel req.session.channel.list() // shows what channels are subscribed to !
  • 130. 2 - Sending to private channels Server (publish to channel) // in a /server/rpc file ss.publish.channel('disney', 'chatMessage', {from: 'jerry', message: 'Has anyone seen Tom?'}); Client (receive channel message) // in a /client/code file ss.event.on('chatMessage', function(msg, channelName){ console.log('The following message was sent to the ' + channelName + ' channel:', msg); });
  • 131. 3 - Sending to users Server // in a /server/rpc file ss.publish.user('fred', 'specialOffer', 'Here is a special offer just for you!');
  • 132. 4 - Sending to a browser tab Server // in a /server/rpc file ss.publish.socketId('254987654324567', 'justForMe', 'Just for one tab');
  • 133. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 134. On top of RPC and PubSub, SocketStream provides you with a way to create custom request responders
  • 135. Request Response is basically a WebSocket message handler
  • 136. It allows you to write message handling for games, where every byte matters
  • 137. HTML / CSS / JS code preprocessing Minifying CSS/JS for production use Client-side code organisation HTML Templates WebSocket Management Live Reload Building RPC APIs Building PubSub APIs Session Management Building custom APIs on top of WS Web Workers Connect middleware compatibility
  • 139. They are mangled by mobile networks…
  • 141. Routed to dead ends by proxy servers
  • 142. And severed by train tunnels
  • 143. Also, browser support for WebSockets isn’t guaranteed
  • 144. You need a transport strategy
  • 146. But Socket.io asserted that if a browser supported WebSockets, then it would work
  • 147. They learned from this, by building Engine.io
  • 148. I created the transport wrapper for Engine.io in SocketStream for Bechtel & Dashku
  • 149. And designed it to reconnect the client when severed
  • 150. Months later, it made it’s way into SocketStream’s core.
  • 151. SocketStream let’s you use this, alongside SockJS
  • 152. …and that is SocketStream in a nutshell. Whew!
  • 153. Let’s look at some SocketStream apps in the wild
  • 162. 1 - Check your server’s ulimit configuration (This can bite you hard)
  • 163. I learned this when Dashku went #1 on Hacker News in 45min
  • 164. 2 - Use HTTPS, but handle it at the load balancer level rather than at the app level
  • 165. HTTPS helps to improve the stability of WebSocket connections, especially on mobile devices
  • 166. But Node’s HTTPS implementation is noticeably slower than using HAProxy or Nginx
  • 168. We’re in the process of getting SocketStream’s test coverage up
  • 169. We’re also trying to close some ancient bugs
  • 170. We also need better documentation
  • 171. We’re giving the web site an overhaul
  • 172. And we want to document how SocketStream’s internals function, to help build 0.4
  • 173. but what about 0.4?
  • 174. …0.4 is starting to look like these:
  • 175. I promise you all, it’s coming in June 2014