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
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
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.
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
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
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
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
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');
});
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
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...
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
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
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
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
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
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.
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
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
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