SlideShare a Scribd company logo
REACTIVE and REALTIME
Web Applications with TurboGears
Alessandro Molina
@__amol__
amol@turbogears.org
Who am I
● CTO @ Axant.it, mostly Python company
(with some iOS and Android)
● TurboGears2 dev team member
● Contributions to web world python libraries
○ MING MongoDB ODM
○ ToscaWidgets2
○ Formencode
Why Realtime
● Web Applications are moving toward
providing data on realtime as soon as it’s
available.
● This requires browser to keep an open
connection to be notified about changes
● Pushing data and Concurrency became
the primary issues
HTTP changing for realtime
● HTTP / 2.0 under work, based on SPDY
● Request/Response multiplexed
○ Single TCP connection with frames described by a
binary protocol (solves some concurrency issues
and speeds up on mobile networks)
● Support for server side pushing data
○ core feature for realtime applications
What’s Reactive
● Reactive Applications automatically
update themselves when data changes.
● Reactive frameworks make easier to
create realtime applications
● Propagating data changes becames the
primary issue.
Where they belong
● Realtime is usually a server side problem
○ Server is the publisher of data changes
○ It has to cope with every single client
● Reactive is usually a client side problem
○ You want to update only the portion of the web
page that changed, not regenerate everything
server side
Time for Mad Science
Solutions for Realtime
● Polling
○ While True: do you have new data?
○ Huge overhead connection setup/teardown
● Long Polling
○ Server will keep the connection open until a
timeout or it has data available.
○ When timeout or data ends client will reopen
connection to wait for next data
Solutions for Realtime #2
● Server Side Events
○ Covers only Server->Client
○ Automatically handles failures and recovery
○ Not supported by IE
● WebSockets
○ Bidirectional communication
○ Supported on modern browsers
Streaming VS Messages
● Streaming
○ Used by Long Polling & SSE
○ Keeps the connection open (blocks client read)
○ Sends data as a unique continuous stream
○ Usually implemented using a generator
● Messages
○ Used by WebSocket and SSE
○ Sends/Receives data as individual message
Server Side Events
# Expose text/event-stream which is the
# content type required to let the browser
# know that we are using SSE
@expose(content_type='text/event-stream')
def data(self, **kw):
# To perform streaming of data (without closing
# the connection) we just return a generator
# instead of returning a string or a dictionary.
def _generator():
while True:
# The generator simply starts fetching data
# from the queue, waiting for new tweets
# to arrive.
value = q.get(block=True)
# When a new tweet is available, format the data
# according to the SSE standard.
event = "data: %s %snn" % (value, time.time())
# Yield data to send it to the client
yield event
# Return the generator which will be streamed back to the browser
return _generator()
Messages with Socket.IO
● Implements messages and events
● Bidirectional
● Abstraction over the underlying available
technology (LongPoll, Flash, WebSocket)
● Provides connection errors handling
● Server side implementation for Python
Socket.IO with TurboGears
● tgext.socketio
○ Provides ready made support for SocketIO
○ SocketIO events are as natural as writing methods
named on_EVENTNAME
○ Based on gevent to avoid blocking concurrent
connections
○ Compatible with Gearbox and PasterServe, no
need for a custom environment
Ping Pong with SocketIO
<html>
<body>
<div>
<a class="ping" href="#" data-attack="ping">Ping</a>
<a class="ping" href="#" data-attack="fireball">Fireball</a>
</div>
<div id="result"></div>
<script src="/javascript/jquery.js"></script>
<script src="/javascript/socket.io.min.js"></script>
<script>
$(function(){
var socket = io.connect('/pingpong', {'resource': 'socketio'});
$('.ping').click(function(event){
socket.emit('ping', {'type': $(this).data('attack')});
});
socket.on('pong', function(data){
$('#result').append(data.sound + '<br/>');
});
});
</script>
</body>
</html>
Ping Pong server side
from tgext.socketio import SocketIOTGNamespace, SocketIOController
class PingPong(SocketIOTGNamespace):
def on_ping(self, attack):
if attack['type'] == 'fireball':
for i in range(10):
self.emit('pong', {'sound':'bang!'})
else:
self.emit('pong', {'sound':'pong'})
class SocketIO(SocketIOController):
pingpong = PingPong
@expose()
def page(self, **kw):
return PAGE_HTML
class RootController(BaseController):
socketio = SocketIO()
Speed alone is not enough
we need some help in managing the added complexity of realtime updates
Adding Reactivity
● Now we are being notified on real time
when something happens
● Then we need to update the web page
accordingly to the change
● Previously achieved by
○ $('#result').append(data.sound + '<br/>');
Ractive.JS
● Declare a Template (Mustache)
● Declare a Model (POJO)
● Join them with Ractive
● Whenever the model changes the
template gets automatically redrawn
● Written in JavaScript
Reactive PingPong
<html>
<body>
<div>
<a href="#" onclick="socket.emit('ping', {'type': 'ping'});">Ping</a>
<a href="#" onclick="socket.emit('ping', {'type': 'fireball'});">Fireball</a>
</div>
<div id="result"></div>
<script src="/ractive.js"></script>
<script src="/socket.io.min.js"></script>
<script id="PingPongWidget_template" type='text/ractive'>
{{#messages:idx}}
<div>{{sound}}</div>
{{/messages}}
</script>
<script>
var pingpong = new Ractive({template: '#PingPongWidget_template',
el: 'result',
data: {'messages': []}
});
var socket = io.connect('/pingpong', {'resource':'socketio'});
socket.on('pong',function(data) {
pingpong.get('messages').push(data);
});
</script>
</body>
</html>
Reactive and Realtime!
Let’s move it back the python side
● Now we ended up with MVCMVC (or MVT)
○ Python Model with Python Controller with a
Python Template on server
○ JS Model with JS Controller and JS Template on
client
● I want to keep a single stack but benefit
from ractive.
○ Let ractive handle all web page widgets
ToscaWidgets2
● Split your web page in a bunch of widgets
● Each widget has its data
● Reload the page to redraw the widget
● Written in Python
● Also provides data validation for the
widget
ToscaWidgets PingPong
from tw2.core import Widget
class PingPongWidget(Widget):
inline_engine_name = 'genshi'
template = '''
<div xmlns:py="http://genshi.edgewall.org/"
py:for="message in w.messages">
${message.sound}
</div>
'''
PingPongWidget.display(messages=[{'sound': 'pong'},
{'sound': 'bang!'}
])
Hey looks like Ractive!
● Both provide entities with a Template
● Both provide support for having data
within those entities
● Ractive automatically updates itself
● ToscaWidgets has data validation and
dependencies injection
Join them, get SuperWidgets!
RactiveWidget
from axf.ractive import RactiveWidget
class PingPongWidget(RactiveWidget):
ractive_params = ['messages']
ractive_template = '''
{{#messages:idx}}
<div>{{sound}}</div>
{{/messages}}
'''
● we did an experiment in AXF library for
ToscaWidgets based Ractive Widgets
PingPong using RactiveWidget
from tg import AppConfig, expose, TGController
from tgext.socketio import SocketIOTGNamespace, SocketIOController
class PingPong(SocketIOTGNamespace):
def on_ping(self, attack):
[...]
class SocketIO(SocketIOController):
pingpong = PingPong
@expose('genshi:page.html')
def page(self, **kw):
return dict(pingpong=PingPongWidget(id='pingpong', messages=[]))
class RootController(TGController):
socketio = SocketIO()
config = AppConfig(minimal=True, root_controller=RootController())
config.serve_static = True
config.renderers = ['genshi']
config.use_toscawidgets2 = True
config.paths['static_files'] = 'public'
print 'Serving on 8080'
from socketio.server import SocketIOServer
SocketIOServer(('0.0.0.0', 8080), config.make_wsgi_app(), resource='socketio').serve_forever()
PingPong Template
<html>
<head>
<script src="/socket.io.min.js"></script>
<script src="/ractive.js"></script>
</head>
<body>
<div>
<a href="#" onclick="socket.emit('ping', {'type': 'ping'});">Ping</a>
<a href="#" onclick="socket.emit('ping', {'type': 'fireball'});">Fireball</a>
</div>
${pingpong.display()}
<script>
var socket = io.connect('/pingpong', {'resource':'socketio'});
socket.on('pong',function(data) {
document.RAWidgets.pingpong.get('messages').push(data);
});
</script>
</body>
</html>
Benefits
● Simpler template, just display a widget and
let it update itself.
● Widget dependencies (JS, CSS and so on)
are brought in by ToscaWidgets itself, no
need to care.
● No need to encode data and pass it from
python to JS, ToscaWidget does that for us
Publish / Subscribe
● The real power of ractive/realtime
programming is unleashed in multiuser
environments
● tgext.socketio has built-in support for
publish/subscribe
● With multiple backends supported
(memory, Redis, mongodb, amqp)
Realtime chat example
● Realtime multiuser chat
● Support for multiple rooms
● Just replace PingPong namespace
● New namespace will inherit from
PubSubTGNamespace instead of
SocketIOTGNamespace
PubSub - Server Side
class ChatNamespace(PubSubTGNamespace):
# PubSubTGNamespace automatically calls subscribe_room
# whenever a client subscribes to a “room” channel.
def subscribe_room(self, roomid):
# Whe generate an user id for the client when it first subscribes
self.session['uid'] = str(uuid.uuid4())
# This is the channel where notifies will be published
self.session['channel'] = 'room-%s' % roomid
# Whe notify the client that his userid is the newly generated one
self.emit('userid', self.session['uid'])
# Tell tgext.socketio for which channel we subscribed
return self.session['channel']
# When the client emits e message, publish it on the
# room so it gets propagated to every subscriber.
def on_user_message(self, message):
self.publish(self.session['channel'], {'uid': self.session['uid'],
'message': message})
PubSub - Client Side
<body>
<div id="chat">
<div id="messages">
<div id="lines"></div>
</div>
<form id="send-message">
<input id="message"> <button>Send</button>
</form>
</div>
<script>
var socket = io.connect('/chat', {'resource':'socketio'});
var userid = null;
socket.on('connect', function () { socket.emit('subscribe', 'room', '1'); });
socket.on('userid', function (myid) { userid = myid; });
socket.on('pubblication', function (data) {
var sender = data.uid;
var msg = data.message;
$('#lines').append($('<p>').append($('<em>').text(msg)));
});
$('#send-message').submit(function () {
socket.emit('user_message', $('#message').val());
$('#message').val('').focus();
return false;
});
</script>
</body>
Questions?

More Related Content

What's hot

Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
ICS
 
Node Architecture and Getting Started with Express
Node Architecture and Getting Started with ExpressNode Architecture and Getting Started with Express
Node Architecture and Getting Started with Express
jguerrero999
 
Qt for Python
Qt for PythonQt for Python
Qt for Python
ICS
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
GITS Indonesia
 
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made EasyLockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
ICS
 
JavaScript on the Desktop
JavaScript on the DesktopJavaScript on the Desktop
JavaScript on the Desktop
Domenic Denicola
 
Zenly - Reverse geocoding
Zenly - Reverse geocodingZenly - Reverse geocoding
Zenly - Reverse geocoding
CocoaHeads France
 
Angular - injection tokens & Custom libraries
Angular - injection tokens & Custom librariesAngular - injection tokens & Custom libraries
Angular - injection tokens & Custom libraries
Eliran Eliassy
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMR
Javier Abadía
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
Katy Slemon
 
Angular 1 + es6
Angular 1 + es6Angular 1 + es6
Angular 1 + es6
장현 한
 
Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3
ICS
 
Are app servers still fascinating
Are app servers still fascinatingAre app servers still fascinating
Are app servers still fascinating
Antonio Goncalves
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
Nir Kaufman
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
fakedarren
 
End to end todo list app with NestJs - Angular - Redux & Redux Saga
End to end todo list app with NestJs - Angular - Redux & Redux SagaEnd to end todo list app with NestJs - Angular - Redux & Redux Saga
End to end todo list app with NestJs - Angular - Redux & Redux Saga
Babacar NIANG
 
"Node.js threads for I/O-bound tasks", Timur Shemsedinov
"Node.js threads for I/O-bound tasks", Timur Shemsedinov"Node.js threads for I/O-bound tasks", Timur Shemsedinov
"Node.js threads for I/O-bound tasks", Timur Shemsedinov
Fwdays
 
In-Depth Model/View with QML
In-Depth Model/View with QMLIn-Depth Model/View with QML
In-Depth Model/View with QML
ICS
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
Jeado Ko
 
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IBest Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part I
ICS
 

What's hot (20)

Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
 
Node Architecture and Getting Started with Express
Node Architecture and Getting Started with ExpressNode Architecture and Getting Started with Express
Node Architecture and Getting Started with Express
 
Qt for Python
Qt for PythonQt for Python
Qt for Python
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
 
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made EasyLockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
 
JavaScript on the Desktop
JavaScript on the DesktopJavaScript on the Desktop
JavaScript on the Desktop
 
Zenly - Reverse geocoding
Zenly - Reverse geocodingZenly - Reverse geocoding
Zenly - Reverse geocoding
 
Angular - injection tokens & Custom libraries
Angular - injection tokens & Custom librariesAngular - injection tokens & Custom libraries
Angular - injection tokens & Custom libraries
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMR
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
Angular 1 + es6
Angular 1 + es6Angular 1 + es6
Angular 1 + es6
 
Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3
 
Are app servers still fascinating
Are app servers still fascinatingAre app servers still fascinating
Are app servers still fascinating
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
End to end todo list app with NestJs - Angular - Redux & Redux Saga
End to end todo list app with NestJs - Angular - Redux & Redux SagaEnd to end todo list app with NestJs - Angular - Redux & Redux Saga
End to end todo list app with NestJs - Angular - Redux & Redux Saga
 
"Node.js threads for I/O-bound tasks", Timur Shemsedinov
"Node.js threads for I/O-bound tasks", Timur Shemsedinov"Node.js threads for I/O-bound tasks", Timur Shemsedinov
"Node.js threads for I/O-bound tasks", Timur Shemsedinov
 
In-Depth Model/View with QML
In-Depth Model/View with QMLIn-Depth Model/View with QML
In-Depth Model/View with QML
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
 
Best Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part IBest Practices in Qt Quick/QML - Part I
Best Practices in Qt Quick/QML - Part I
 

Similar to Reactive & Realtime Web Applications with TurboGears2

20180518 QNAP Seminar - Introduction to React Native
20180518 QNAP Seminar - Introduction to React Native20180518 QNAP Seminar - Introduction to React Native
20180518 QNAP Seminar - Introduction to React Native
Eric Deng
 
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache BeamGDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
Imre Nagi
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
Tudor Barbu
 
Google Wave API: Now and Beyond
Google Wave API: Now and BeyondGoogle Wave API: Now and Beyond
Google Wave API: Now and Beyond
Marakana Inc.
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
Ignacio Martín
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
Gonzalo Ayuso
 
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
Alessandro Molina
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
deimos
 
Spring 4 Web App
Spring 4 Web AppSpring 4 Web App
Spring 4 Web App
Rossen Stoyanchev
 
Power ai image-pipeline
Power ai image-pipelinePower ai image-pipeline
Power ai image-pipeline
Paulo Sergio Lemes Queiroz
 
Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server Internals
Praveen Gollakota
 
An approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSocketsAn approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSockets
Andrei Sebastian Cîmpean
 
Necto 16 training 20 component mode &amp; java script
Necto 16 training 20   component mode &amp; java scriptNecto 16 training 20   component mode &amp; java script
Necto 16 training 20 component mode &amp; java script
Panorama Software
 
Angular - Chapter 4 - Data and Event Handling
 Angular - Chapter 4 - Data and Event Handling Angular - Chapter 4 - Data and Event Handling
Angular - Chapter 4 - Data and Event Handling
WebStackAcademy
 
Using Groovy to empower WebRTC Network Systems
Using Groovy to empower WebRTC Network SystemsUsing Groovy to empower WebRTC Network Systems
Using Groovy to empower WebRTC Network Systems
antonry
 
Revealing ALLSTOCKER
Revealing ALLSTOCKERRevealing ALLSTOCKER
Revealing ALLSTOCKER
Masashi Umezawa
 
FIWARE Developers Week_BootcampWeBUI_presentation1
FIWARE Developers Week_BootcampWeBUI_presentation1FIWARE Developers Week_BootcampWeBUI_presentation1
FIWARE Developers Week_BootcampWeBUI_presentation1
FIWARE
 
Live Streaming & Server Sent Events
Live Streaming & Server Sent EventsLive Streaming & Server Sent Events
Live Streaming & Server Sent Events
tkramar
 
27 - Panorama Necto 14 component mode & java script - visualization & data di...
27 - Panorama Necto 14 component mode & java script - visualization & data di...27 - Panorama Necto 14 component mode & java script - visualization & data di...
27 - Panorama Necto 14 component mode & java script - visualization & data di...
Panorama Software
 
How to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchHow to build twitter bot using golang from scratch
How to build twitter bot using golang from scratch
Katy Slemon
 

Similar to Reactive & Realtime Web Applications with TurboGears2 (20)

20180518 QNAP Seminar - Introduction to React Native
20180518 QNAP Seminar - Introduction to React Native20180518 QNAP Seminar - Introduction to React Native
20180518 QNAP Seminar - Introduction to React Native
 
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache BeamGDG Jakarta Meetup - Streaming Analytics With Apache Beam
GDG Jakarta Meetup - Streaming Analytics With Apache Beam
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
Google Wave API: Now and Beyond
Google Wave API: Now and BeyondGoogle Wave API: Now and Beyond
Google Wave API: Now and Beyond
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
 
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
 
Spring 4 Web App
Spring 4 Web AppSpring 4 Web App
Spring 4 Web App
 
Power ai image-pipeline
Power ai image-pipelinePower ai image-pipeline
Power ai image-pipeline
 
Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server Internals
 
An approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSocketsAn approach to responsive, realtime with Backbone.js and WebSockets
An approach to responsive, realtime with Backbone.js and WebSockets
 
Necto 16 training 20 component mode &amp; java script
Necto 16 training 20   component mode &amp; java scriptNecto 16 training 20   component mode &amp; java script
Necto 16 training 20 component mode &amp; java script
 
Angular - Chapter 4 - Data and Event Handling
 Angular - Chapter 4 - Data and Event Handling Angular - Chapter 4 - Data and Event Handling
Angular - Chapter 4 - Data and Event Handling
 
Using Groovy to empower WebRTC Network Systems
Using Groovy to empower WebRTC Network SystemsUsing Groovy to empower WebRTC Network Systems
Using Groovy to empower WebRTC Network Systems
 
Revealing ALLSTOCKER
Revealing ALLSTOCKERRevealing ALLSTOCKER
Revealing ALLSTOCKER
 
FIWARE Developers Week_BootcampWeBUI_presentation1
FIWARE Developers Week_BootcampWeBUI_presentation1FIWARE Developers Week_BootcampWeBUI_presentation1
FIWARE Developers Week_BootcampWeBUI_presentation1
 
Live Streaming & Server Sent Events
Live Streaming & Server Sent EventsLive Streaming & Server Sent Events
Live Streaming & Server Sent Events
 
27 - Panorama Necto 14 component mode & java script - visualization & data di...
27 - Panorama Necto 14 component mode & java script - visualization & data di...27 - Panorama Necto 14 component mode & java script - visualization & data di...
27 - Panorama Necto 14 component mode & java script - visualization & data di...
 
How to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchHow to build twitter bot using golang from scratch
How to build twitter bot using golang from scratch
 

More from Alessandro Molina

PyCon Ireland 2022 - PyArrow full stack.pdf
PyCon Ireland 2022 - PyArrow full stack.pdfPyCon Ireland 2022 - PyArrow full stack.pdf
PyCon Ireland 2022 - PyArrow full stack.pdf
Alessandro Molina
 
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsEP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
Alessandro Molina
 
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
EuroPython 2015 - Storing files for the web is not as straightforward as you ...EuroPython 2015 - Storing files for the web is not as straightforward as you ...
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
Alessandro Molina
 
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATESPyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
Alessandro Molina
 
PyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profitPyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profit
Alessandro Molina
 
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PyConFR 2014 - DEPOT, Story of a file.write() gone wrongPyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
Alessandro Molina
 
PyConUK 2014 - PostMortem Debugging and Web Development Updated
PyConUK 2014 - PostMortem Debugging and Web Development UpdatedPyConUK 2014 - PostMortem Debugging and Web Development Updated
PyConUK 2014 - PostMortem Debugging and Web Development Updated
Alessandro Molina
 
Post-Mortem Debugging and Web Development
Post-Mortem Debugging and Web DevelopmentPost-Mortem Debugging and Web Development
Post-Mortem Debugging and Web Development
Alessandro Molina
 
MongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profitMongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profit
Alessandro Molina
 
PyConUK2013 - Validated documents on MongoDB with Ming
PyConUK2013 - Validated documents on MongoDB with MingPyConUK2013 - Validated documents on MongoDB with Ming
PyConUK2013 - Validated documents on MongoDB with Ming
Alessandro Molina
 
EuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears TrainingEuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears Training
Alessandro Molina
 
PyGrunn2013 High Performance Web Applications with TurboGears
PyGrunn2013  High Performance Web Applications with TurboGearsPyGrunn2013  High Performance Web Applications with TurboGears
PyGrunn2013 High Performance Web Applications with TurboGears
Alessandro Molina
 
Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2
Alessandro Molina
 
TurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsTurboGears2 Pluggable Applications
TurboGears2 Pluggable Applications
Alessandro Molina
 

More from Alessandro Molina (14)

PyCon Ireland 2022 - PyArrow full stack.pdf
PyCon Ireland 2022 - PyArrow full stack.pdfPyCon Ireland 2022 - PyArrow full stack.pdf
PyCon Ireland 2022 - PyArrow full stack.pdf
 
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsEP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
 
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
EuroPython 2015 - Storing files for the web is not as straightforward as you ...EuroPython 2015 - Storing files for the web is not as straightforward as you ...
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
 
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATESPyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
 
PyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profitPyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profit
 
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PyConFR 2014 - DEPOT, Story of a file.write() gone wrongPyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
 
PyConUK 2014 - PostMortem Debugging and Web Development Updated
PyConUK 2014 - PostMortem Debugging and Web Development UpdatedPyConUK 2014 - PostMortem Debugging and Web Development Updated
PyConUK 2014 - PostMortem Debugging and Web Development Updated
 
Post-Mortem Debugging and Web Development
Post-Mortem Debugging and Web DevelopmentPost-Mortem Debugging and Web Development
Post-Mortem Debugging and Web Development
 
MongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profitMongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profit
 
PyConUK2013 - Validated documents on MongoDB with Ming
PyConUK2013 - Validated documents on MongoDB with MingPyConUK2013 - Validated documents on MongoDB with Ming
PyConUK2013 - Validated documents on MongoDB with Ming
 
EuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears TrainingEuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears Training
 
PyGrunn2013 High Performance Web Applications with TurboGears
PyGrunn2013  High Performance Web Applications with TurboGearsPyGrunn2013  High Performance Web Applications with TurboGears
PyGrunn2013 High Performance Web Applications with TurboGears
 
Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2
 
TurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsTurboGears2 Pluggable Applications
TurboGears2 Pluggable Applications
 

Recently uploaded

AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
HarisZaheer8
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
GDSC PJATK
 
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdfNunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
flufftailshop
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Tatiana Kojar
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
shyamraj55
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
Tomaz Bratanic
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 

Recently uploaded (20)

AWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptxAWS Cloud Cost Optimization Presentation.pptx
AWS Cloud Cost Optimization Presentation.pptx
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
 
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdfNunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
Nunit vs XUnit vs MSTest Differences Between These Unit Testing Frameworks.pdf
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
Skybuffer AI: Advanced Conversational and Generative AI Solution on SAP Busin...
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with SlackLet's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
Let's Integrate MuleSoft RPA, COMPOSER, APM with AWS IDP along with Slack
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
GraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracyGraphRAG for Life Science to increase LLM accuracy
GraphRAG for Life Science to increase LLM accuracy
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 

Reactive & Realtime Web Applications with TurboGears2

  • 1. REACTIVE and REALTIME Web Applications with TurboGears Alessandro Molina @__amol__ amol@turbogears.org
  • 2. Who am I ● CTO @ Axant.it, mostly Python company (with some iOS and Android) ● TurboGears2 dev team member ● Contributions to web world python libraries ○ MING MongoDB ODM ○ ToscaWidgets2 ○ Formencode
  • 3. Why Realtime ● Web Applications are moving toward providing data on realtime as soon as it’s available. ● This requires browser to keep an open connection to be notified about changes ● Pushing data and Concurrency became the primary issues
  • 4. HTTP changing for realtime ● HTTP / 2.0 under work, based on SPDY ● Request/Response multiplexed ○ Single TCP connection with frames described by a binary protocol (solves some concurrency issues and speeds up on mobile networks) ● Support for server side pushing data ○ core feature for realtime applications
  • 5. What’s Reactive ● Reactive Applications automatically update themselves when data changes. ● Reactive frameworks make easier to create realtime applications ● Propagating data changes becames the primary issue.
  • 6. Where they belong ● Realtime is usually a server side problem ○ Server is the publisher of data changes ○ It has to cope with every single client ● Reactive is usually a client side problem ○ You want to update only the portion of the web page that changed, not regenerate everything server side
  • 7. Time for Mad Science
  • 8. Solutions for Realtime ● Polling ○ While True: do you have new data? ○ Huge overhead connection setup/teardown ● Long Polling ○ Server will keep the connection open until a timeout or it has data available. ○ When timeout or data ends client will reopen connection to wait for next data
  • 9. Solutions for Realtime #2 ● Server Side Events ○ Covers only Server->Client ○ Automatically handles failures and recovery ○ Not supported by IE ● WebSockets ○ Bidirectional communication ○ Supported on modern browsers
  • 10. Streaming VS Messages ● Streaming ○ Used by Long Polling & SSE ○ Keeps the connection open (blocks client read) ○ Sends data as a unique continuous stream ○ Usually implemented using a generator ● Messages ○ Used by WebSocket and SSE ○ Sends/Receives data as individual message
  • 11. Server Side Events # Expose text/event-stream which is the # content type required to let the browser # know that we are using SSE @expose(content_type='text/event-stream') def data(self, **kw): # To perform streaming of data (without closing # the connection) we just return a generator # instead of returning a string or a dictionary. def _generator(): while True: # The generator simply starts fetching data # from the queue, waiting for new tweets # to arrive. value = q.get(block=True) # When a new tweet is available, format the data # according to the SSE standard. event = "data: %s %snn" % (value, time.time()) # Yield data to send it to the client yield event # Return the generator which will be streamed back to the browser return _generator()
  • 12. Messages with Socket.IO ● Implements messages and events ● Bidirectional ● Abstraction over the underlying available technology (LongPoll, Flash, WebSocket) ● Provides connection errors handling ● Server side implementation for Python
  • 13. Socket.IO with TurboGears ● tgext.socketio ○ Provides ready made support for SocketIO ○ SocketIO events are as natural as writing methods named on_EVENTNAME ○ Based on gevent to avoid blocking concurrent connections ○ Compatible with Gearbox and PasterServe, no need for a custom environment
  • 14. Ping Pong with SocketIO <html> <body> <div> <a class="ping" href="#" data-attack="ping">Ping</a> <a class="ping" href="#" data-attack="fireball">Fireball</a> </div> <div id="result"></div> <script src="/javascript/jquery.js"></script> <script src="/javascript/socket.io.min.js"></script> <script> $(function(){ var socket = io.connect('/pingpong', {'resource': 'socketio'}); $('.ping').click(function(event){ socket.emit('ping', {'type': $(this).data('attack')}); }); socket.on('pong', function(data){ $('#result').append(data.sound + '<br/>'); }); }); </script> </body> </html>
  • 15. Ping Pong server side from tgext.socketio import SocketIOTGNamespace, SocketIOController class PingPong(SocketIOTGNamespace): def on_ping(self, attack): if attack['type'] == 'fireball': for i in range(10): self.emit('pong', {'sound':'bang!'}) else: self.emit('pong', {'sound':'pong'}) class SocketIO(SocketIOController): pingpong = PingPong @expose() def page(self, **kw): return PAGE_HTML class RootController(BaseController): socketio = SocketIO()
  • 16. Speed alone is not enough we need some help in managing the added complexity of realtime updates
  • 17. Adding Reactivity ● Now we are being notified on real time when something happens ● Then we need to update the web page accordingly to the change ● Previously achieved by ○ $('#result').append(data.sound + '<br/>');
  • 18. Ractive.JS ● Declare a Template (Mustache) ● Declare a Model (POJO) ● Join them with Ractive ● Whenever the model changes the template gets automatically redrawn ● Written in JavaScript
  • 19. Reactive PingPong <html> <body> <div> <a href="#" onclick="socket.emit('ping', {'type': 'ping'});">Ping</a> <a href="#" onclick="socket.emit('ping', {'type': 'fireball'});">Fireball</a> </div> <div id="result"></div> <script src="/ractive.js"></script> <script src="/socket.io.min.js"></script> <script id="PingPongWidget_template" type='text/ractive'> {{#messages:idx}} <div>{{sound}}</div> {{/messages}} </script> <script> var pingpong = new Ractive({template: '#PingPongWidget_template', el: 'result', data: {'messages': []} }); var socket = io.connect('/pingpong', {'resource':'socketio'}); socket.on('pong',function(data) { pingpong.get('messages').push(data); }); </script> </body> </html>
  • 21. Let’s move it back the python side ● Now we ended up with MVCMVC (or MVT) ○ Python Model with Python Controller with a Python Template on server ○ JS Model with JS Controller and JS Template on client ● I want to keep a single stack but benefit from ractive. ○ Let ractive handle all web page widgets
  • 22. ToscaWidgets2 ● Split your web page in a bunch of widgets ● Each widget has its data ● Reload the page to redraw the widget ● Written in Python ● Also provides data validation for the widget
  • 23. ToscaWidgets PingPong from tw2.core import Widget class PingPongWidget(Widget): inline_engine_name = 'genshi' template = ''' <div xmlns:py="http://genshi.edgewall.org/" py:for="message in w.messages"> ${message.sound} </div> ''' PingPongWidget.display(messages=[{'sound': 'pong'}, {'sound': 'bang!'} ])
  • 24. Hey looks like Ractive! ● Both provide entities with a Template ● Both provide support for having data within those entities ● Ractive automatically updates itself ● ToscaWidgets has data validation and dependencies injection
  • 25. Join them, get SuperWidgets!
  • 26. RactiveWidget from axf.ractive import RactiveWidget class PingPongWidget(RactiveWidget): ractive_params = ['messages'] ractive_template = ''' {{#messages:idx}} <div>{{sound}}</div> {{/messages}} ''' ● we did an experiment in AXF library for ToscaWidgets based Ractive Widgets
  • 27. PingPong using RactiveWidget from tg import AppConfig, expose, TGController from tgext.socketio import SocketIOTGNamespace, SocketIOController class PingPong(SocketIOTGNamespace): def on_ping(self, attack): [...] class SocketIO(SocketIOController): pingpong = PingPong @expose('genshi:page.html') def page(self, **kw): return dict(pingpong=PingPongWidget(id='pingpong', messages=[])) class RootController(TGController): socketio = SocketIO() config = AppConfig(minimal=True, root_controller=RootController()) config.serve_static = True config.renderers = ['genshi'] config.use_toscawidgets2 = True config.paths['static_files'] = 'public' print 'Serving on 8080' from socketio.server import SocketIOServer SocketIOServer(('0.0.0.0', 8080), config.make_wsgi_app(), resource='socketio').serve_forever()
  • 28. PingPong Template <html> <head> <script src="/socket.io.min.js"></script> <script src="/ractive.js"></script> </head> <body> <div> <a href="#" onclick="socket.emit('ping', {'type': 'ping'});">Ping</a> <a href="#" onclick="socket.emit('ping', {'type': 'fireball'});">Fireball</a> </div> ${pingpong.display()} <script> var socket = io.connect('/pingpong', {'resource':'socketio'}); socket.on('pong',function(data) { document.RAWidgets.pingpong.get('messages').push(data); }); </script> </body> </html>
  • 29. Benefits ● Simpler template, just display a widget and let it update itself. ● Widget dependencies (JS, CSS and so on) are brought in by ToscaWidgets itself, no need to care. ● No need to encode data and pass it from python to JS, ToscaWidget does that for us
  • 30. Publish / Subscribe ● The real power of ractive/realtime programming is unleashed in multiuser environments ● tgext.socketio has built-in support for publish/subscribe ● With multiple backends supported (memory, Redis, mongodb, amqp)
  • 31. Realtime chat example ● Realtime multiuser chat ● Support for multiple rooms ● Just replace PingPong namespace ● New namespace will inherit from PubSubTGNamespace instead of SocketIOTGNamespace
  • 32. PubSub - Server Side class ChatNamespace(PubSubTGNamespace): # PubSubTGNamespace automatically calls subscribe_room # whenever a client subscribes to a “room” channel. def subscribe_room(self, roomid): # Whe generate an user id for the client when it first subscribes self.session['uid'] = str(uuid.uuid4()) # This is the channel where notifies will be published self.session['channel'] = 'room-%s' % roomid # Whe notify the client that his userid is the newly generated one self.emit('userid', self.session['uid']) # Tell tgext.socketio for which channel we subscribed return self.session['channel'] # When the client emits e message, publish it on the # room so it gets propagated to every subscriber. def on_user_message(self, message): self.publish(self.session['channel'], {'uid': self.session['uid'], 'message': message})
  • 33. PubSub - Client Side <body> <div id="chat"> <div id="messages"> <div id="lines"></div> </div> <form id="send-message"> <input id="message"> <button>Send</button> </form> </div> <script> var socket = io.connect('/chat', {'resource':'socketio'}); var userid = null; socket.on('connect', function () { socket.emit('subscribe', 'room', '1'); }); socket.on('userid', function (myid) { userid = myid; }); socket.on('pubblication', function (data) { var sender = data.uid; var msg = data.message; $('#lines').append($('<p>').append($('<em>').text(msg))); }); $('#send-message').submit(function () { socket.emit('user_message', $('#message').val()); $('#message').val('').focus(); return false; }); </script> </body>