SlideShare uma empresa Scribd logo
1 de 49
Baixar para ler offline
Python, WebRTC and You
Saúl Ibarra Corretgé

@saghul
v2
github.com/saghul
WebRTC, anyone?
Have you ever used it?
Internals, anyone?
What is WebRTC?
WebRTC (Web Real-Time Communication) is an API
definition drafted by the World Wide Web Consortium
(W3C) that supports browser-to-browser applications
for voice calling, video chat, and P2P file sharing
without the need of either internal or external plugins.
Well,
everyone
better
Restart
Their
Chrome
You need an adapter
Implementation in browsers is
currently inconsistent

Some APIs are still in flux
rtcninja.js
https://github.com/eface2face/rtcninja.js

Nice name, right?!
Temasys WebRTC
Plugin
Free (as in beer) plugin for IE and
Safari

http://skylink.io/plugin/
WebRTC APIs
getUserMedia

RTCPeerConnection

RTCDataChannel
getUserMedia
if (!rtcninja.hasWebRTC()) {	
console.log('Are you from the past?!');	
return;	
}	
!
rtcninja.getUserMedia(	
// constraints	
{video: true, audio: true},	
!
// successCallback	
function(localMediaStream) {	
var video = document.querySelector('video');	
rtcninja.attachMediaStream(video, localMediaStream);	
},	
!
// errorCallback	
function(err) {	
console.log("The following error occured: " + err);	
}	
);
RTCPeerConnection
Handles streaming of media between
2 peers

Uses state of the art technology

JSEP
RTCPeerConnection (2)
Get local media Send SDP offer
Get local media
Send SDP answer
ICE candidates
Audio / Video
Interactive Connectivity Establishment
ICE
Helps find the best path for media

Solves NAT traversal and other
hostile network problems

Communication Consent Verification

It can trickle!
What about the
signalling?
It’s not specified!

Use SIP, XMPP or roll your own!
RTCDataChannel
P2P, message boundary based
channel for arbitrary data

Implemented using SCTP, different
reliability choices possible
Call Roulette
Python
JavaScript
The Protocol
WebSocket based, JSON payload

Users enter the roulette when they
connect over WebSocket

Session is negotiated / established

No end message, just disconnect the
WebSocket
Saghul’s Imbecile Protocol
(v1)
yo
(v2)
{'yo': 'yo'}
{'jsep': {'sdp': '...',	
'type': 'offer'},	
'yo': 'yo'}
{'jsep': {'sdp': '...',	
'type': 'answer'},	
'yo': 'yo'}
{'candidate': {'candidate': '...',	
'sdpMLineIndex': 1,	
'sdpMid': ''},	
'yo': 'yo'}
Shopping for a
framework
Python >= 3.3, because future!

WebSocket support built-in

Async, because blocking is so 2001

New, because why not?
asyncio + aiohttp
github.com/saghul/CallRoulette
@asyncio.coroutine	
def init(loop):	
app = web.Application(loop=loop)	
app.router.add_route('GET', '/', LazyFileHandler(INDEX_FILE, 'text/html'))	
app.router.add_route('GET', '/ws', WebSocketHandler())	
app.router.add_route('GET', '/static/{path:.*}', StaticFilesHandler(STATIC_FILES))	
!
handler = app.make_handler()	
server = yield from loop.create_server(handler, '0.0.0.0', 8080)	
print("Server started at http://0.0.0.0:8080")	
return server, handler
class StaticFilesHandler:	
def __init__(self, base_path):	
self.base_path = base_path	
self.cache = {}	
!
@asyncio.coroutine	
def __call__(self, request):	
path = request.match_info['path']	
try:	
data, content_type = self.cache[path]	
except KeyError:	
full_path = os.path.join(self.base_path, path)	
try:	
with open(full_path, 'rb') as f:	
content_type, encoding = mimetypes.guess_type(full_path,	
strict=False)	
data = f.read()	
except IOError:	
log.warning('Could not open %s file' % path)	
raise web.HTTPNotFound()	
self.cache[path] = data, content_type	
log.debug('Loaded file %s (%s)' % (path, content_type))	
return web.Response(body=data, content_type=content_type)
class WebSocketHandler:	
def __init__(self):	
self.waiter = None	
!
@asyncio.coroutine	
def __call__(self, request):	
ws = web.WebSocketResponse(protocols=('callroulette-v2',))	
ws.start(request)	
!
conn = Connection(ws)	
if self.waiter is None:	
self.waiter = asyncio.Future(loop=ws._loop)	
fs = [conn.read(), self.waiter]	
done, pending = yield from asyncio.wait(fs, return_when=asyncio.FIRST_COMPLETED)	
if self.waiter not in done:	
# the connection was most likely closed	
self.waiter = None	
return ws	
other = self.waiter.result()	
self.waiter = None	
reading_task = pending.pop()

reading_task.cancel()	
asyncio.async(self.run_roulette(conn, other))	
else:	
self.waiter.set_result(conn)	
!
yield from conn.wait_closed()	
!
return ws
from jsonmodels import models, fields	
from jsonmodels.errors import ValidationError	
!
!
class StringChoiceField(fields.StringField):	
def __init__(self, choices=None, *args, **kw):	
self.choices = choices or []	
super(StringChoiceField, self).__init__(*args, **kw)	
!
def validate(self, value):	
if value not in self.choices:	
raise ValidationError('invalid choice value')	
super(StringChoiceField, self).validate(value)	
!
class Jsep(models.Base):	
type = StringChoiceField(choices=['offer', 'answer'], required=True)	
sdp = fields.StringField(required=True)	
!
class Candidate(models.Base):	
candidate = fields.StringField(required=True)	
sdpMid = fields.StringField(required=True)	
sdpMLineIndex = fields.IntField(required=True)	
!
class YoPayload(models.Base):	
yo = fields.StringField(required=True)	
jsep = fields.EmbeddedField(Jsep)	
candidate = fields.EmbeddedField(Candidate)
@asyncio.coroutine	
def run_roulette(self, peerA, peerB):	
log.info('Running roulette: %s, %s' % (peerA, peerB))	
!
@asyncio.coroutine	
def close_connections():	
yield from asyncio.wait([peerA.close(), peerB.close()],

return_when=asyncio.ALL_COMPLETED)	
!
def parse(data):	
try:	
data = json.loads(data)	
payload = YoPayload(**data)	
payload.validate()	
except Exception as e:	
log.warning('Error parsing payload: %s' % e)	
return None	
return payload
# request offer	
offer_request = YoPayload(yo='yo')	
peerA.write(json.dumps(offer_request.to_struct()))	
!
# get offer	
data = yield from peerA.read(timeout=READ_TIMEOUT)	
if not data:	
yield from close_connections()	
return	
!
offer = parse(data)	
if offer is None or offer.jsep is None or offer.jsep.type != 'offer':	
log.warning('Invalid offer received')	
yield from close_connections()	
return	
!
# send offer	
peerB.write(json.dumps(offer.to_struct()))
# wait for answer	
data = yield from peerB.read(timeout=READ_TIMEOUT)	
if not data:	
yield from close_connections()	
return	
!
answer = parse(data)	
if answer is None or answer.jsep is None or answer.jsep.type != 'answer':	
log.warning('Invalid answer received')	
yield from close_connections()	
return	
!
# dispatch answer	
peerA.write(json.dumps(answer.to_struct()))
# wait for candidates / end	
while True:	
peer_a_read = asyncio.async(peerA.read())	
peer_a_read.other_peer = peerB	
peer_b_read = asyncio.async(peerB.read())	
peer_b_read.other_peer = peerA	
done, pending = yield from asyncio.wait([peer_a_read, peer_b_read],	
return_when=asyncio.FIRST_COMPLETED)	
for task in pending:	
task.cancel()	
for task in done:	
data = task.result()	
if not data:	
break	
# all we can get at this point is trickled ICE candidates	
candidate = parse(data)	
if candidate is None or candidate.candidate is None:	
log.warning('Invalid candidate received!')	
break	
task.other_peer.write(json.dumps(candidate.to_struct()))	
else:	
continue	
break	
# close connections	
yield from close_connections()
In WebRTC trouble?
bettercallsaghul.com
@saghul

Mais conteúdo relacionado

Mais procurados

Perl Dancer for Python programmers
Perl Dancer for Python programmersPerl Dancer for Python programmers
Perl Dancer for Python programmersxSawyer
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Alberto Perdomo
 
Firefox OS Introduction at Bontouch
Firefox OS Introduction at BontouchFirefox OS Introduction at Bontouch
Firefox OS Introduction at BontouchRobert Nyman
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsDylan Jay
 
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet
 
HTML5 Real-Time and Connectivity
HTML5 Real-Time and ConnectivityHTML5 Real-Time and Connectivity
HTML5 Real-Time and ConnectivityPeter Lubbers
 
Real time server
Real time serverReal time server
Real time serverthepian
 
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017Ryan Weaver
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server renderingZiad Saab
 
WordPress mit Composer und Git verwalten
WordPress mit Composer und Git verwaltenWordPress mit Composer und Git verwalten
WordPress mit Composer und Git verwaltenWalter Ebert
 
The goodies of zope, pyramid, and plone (2)
The goodies of zope, pyramid, and plone (2)The goodies of zope, pyramid, and plone (2)
The goodies of zope, pyramid, and plone (2)Dylan Jay
 
Composer
ComposerComposer
Composercmodijk
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsSolution4Future
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Lar21
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATIONkrutitrivedi
 

Mais procurados (20)

Perl Dancer for Python programmers
Perl Dancer for Python programmersPerl Dancer for Python programmers
Perl Dancer for Python programmers
 
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
Strangers In The Night: Ruby, Rack y Sinatra - Herramientas potentes para con...
 
Sprockets
SprocketsSprockets
Sprockets
 
Firefox OS Introduction at Bontouch
Firefox OS Introduction at BontouchFirefox OS Introduction at Bontouch
Firefox OS Introduction at Bontouch
 
Pyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web appsPyramid Lighter/Faster/Better web apps
Pyramid Lighter/Faster/Better web apps
 
CouchDB Google
CouchDB GoogleCouchDB Google
CouchDB Google
 
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
Puppet Camp Phoenix 2015: Managing Files via Puppet: Let Me Count The Ways (B...
 
HTML5 Real-Time and Connectivity
HTML5 Real-Time and ConnectivityHTML5 Real-Time and Connectivity
HTML5 Real-Time and Connectivity
 
Real time server
Real time serverReal time server
Real time server
 
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server rendering
 
WordPress mit Composer und Git verwalten
WordPress mit Composer und Git verwaltenWordPress mit Composer und Git verwalten
WordPress mit Composer und Git verwalten
 
The goodies of zope, pyramid, and plone (2)
The goodies of zope, pyramid, and plone (2)The goodies of zope, pyramid, and plone (2)
The goodies of zope, pyramid, and plone (2)
 
Composer
ComposerComposer
Composer
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutions
 
Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18Flask - Backend com Python - Semcomp 18
Flask - Backend com Python - Semcomp 18
 
Cors michael
Cors michaelCors michael
Cors michael
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATION
 

Destaque

CDRTool: CDR mediation and rating engine for OpenSIPS
CDRTool: CDR mediation and rating engine for OpenSIPSCDRTool: CDR mediation and rating engine for OpenSIPS
CDRTool: CDR mediation and rating engine for OpenSIPSSaúl Ibarra Corretgé
 
WebRTC enabling your OpenSIPS infrastructure
WebRTC enabling your OpenSIPS infrastructureWebRTC enabling your OpenSIPS infrastructure
WebRTC enabling your OpenSIPS infrastructureSaúl Ibarra Corretgé
 
libuv, NodeJS and everything in between
libuv, NodeJS and everything in betweenlibuv, NodeJS and everything in between
libuv, NodeJS and everything in betweenSaúl Ibarra Corretgé
 
Building an Open Source VoIP Hardware Phone
Building an Open Source VoIP Hardware PhoneBuilding an Open Source VoIP Hardware Phone
Building an Open Source VoIP Hardware PhoneSaúl Ibarra Corretgé
 
SylkServer: State of the art RTC application server
SylkServer: State of the art RTC application serverSylkServer: State of the art RTC application server
SylkServer: State of the art RTC application serverSaúl Ibarra Corretgé
 
Escalabilidad horizontal desde las trincheras
Escalabilidad horizontal desde las trincherasEscalabilidad horizontal desde las trincheras
Escalabilidad horizontal desde las trincherasSaúl Ibarra Corretgé
 
libuv: cross platform asynchronous i/o
libuv: cross platform asynchronous i/olibuv: cross platform asynchronous i/o
libuv: cross platform asynchronous i/oSaúl Ibarra Corretgé
 
Videoconferencias: el santo grial de WebRTC
Videoconferencias: el santo grial de WebRTCVideoconferencias: el santo grial de WebRTC
Videoconferencias: el santo grial de WebRTCSaúl Ibarra Corretgé
 
Developing rich SIP applications with SIPSIMPLE SDK
Developing rich SIP applications with SIPSIMPLE SDKDeveloping rich SIP applications with SIPSIMPLE SDK
Developing rich SIP applications with SIPSIMPLE SDKSaúl Ibarra Corretgé
 

Destaque (20)

Python, WebRTC and You
Python, WebRTC and YouPython, WebRTC and You
Python, WebRTC and You
 
Planning libuv v2
Planning libuv v2Planning libuv v2
Planning libuv v2
 
CDRTool: CDR mediation and rating engine for OpenSIPS
CDRTool: CDR mediation and rating engine for OpenSIPSCDRTool: CDR mediation and rating engine for OpenSIPS
CDRTool: CDR mediation and rating engine for OpenSIPS
 
Trust No One
Trust No OneTrust No One
Trust No One
 
The Future of the PBX
The Future of the PBXThe Future of the PBX
The Future of the PBX
 
WebRTC enabling your OpenSIPS infrastructure
WebRTC enabling your OpenSIPS infrastructureWebRTC enabling your OpenSIPS infrastructure
WebRTC enabling your OpenSIPS infrastructure
 
libuv, NodeJS and everything in between
libuv, NodeJS and everything in betweenlibuv, NodeJS and everything in between
libuv, NodeJS and everything in between
 
Building an Open Source VoIP Hardware Phone
Building an Open Source VoIP Hardware PhoneBuilding an Open Source VoIP Hardware Phone
Building an Open Source VoIP Hardware Phone
 
From SIP to WebRTC and vice versa
From SIP to WebRTC and vice versaFrom SIP to WebRTC and vice versa
From SIP to WebRTC and vice versa
 
Proyecto Open Pi Phone
Proyecto Open Pi PhoneProyecto Open Pi Phone
Proyecto Open Pi Phone
 
SylkServer: State of the art RTC application server
SylkServer: State of the art RTC application serverSylkServer: State of the art RTC application server
SylkServer: State of the art RTC application server
 
Escalabilidad horizontal desde las trincheras
Escalabilidad horizontal desde las trincherasEscalabilidad horizontal desde las trincheras
Escalabilidad horizontal desde las trincheras
 
A deep dive into libuv
A deep dive into libuvA deep dive into libuv
A deep dive into libuv
 
libuv: cross platform asynchronous i/o
libuv: cross platform asynchronous i/olibuv: cross platform asynchronous i/o
libuv: cross platform asynchronous i/o
 
Videoconferencias: el santo grial de WebRTC
Videoconferencias: el santo grial de WebRTCVideoconferencias: el santo grial de WebRTC
Videoconferencias: el santo grial de WebRTC
 
Jitsi: State of the Union
Jitsi: State of the UnionJitsi: State of the Union
Jitsi: State of the Union
 
Asyncio
AsyncioAsyncio
Asyncio
 
Introduction to asyncio
Introduction to asyncioIntroduction to asyncio
Introduction to asyncio
 
Rethinking the PBX
Rethinking the PBXRethinking the PBX
Rethinking the PBX
 
Developing rich SIP applications with SIPSIMPLE SDK
Developing rich SIP applications with SIPSIMPLE SDKDeveloping rich SIP applications with SIPSIMPLE SDK
Developing rich SIP applications with SIPSIMPLE SDK
 

Semelhante a Python, WebRTC and You (v2)

soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch
 
Django + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoJavier Abadía
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with WingsRemy Sharp
 
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 HMRJavier Abadía
 
SwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupSwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupErnest Jumbe
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSocketsGonzalo Ayuso
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftOleksandr Stepanov
 
An Introduction To jQuery
An Introduction To jQueryAn Introduction To jQuery
An Introduction To jQueryAndy Gibson
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?Ankara JUG
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Remy Sharp
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02PL dream
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Yevgeniy Brikman
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineAndy McKay
 
Intro to JavaFX & Widget FX
Intro to JavaFX & Widget FXIntro to JavaFX & Widget FX
Intro to JavaFX & Widget FXStephen Chin
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Ngoc Dao
 

Semelhante a Python, WebRTC and You (v2) (20)

soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
Django + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar Django
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with Wings
 
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
 
SwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupSwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup Group
 
A More Flash Like Web?
A More Flash Like Web?A More Flash Like Web?
A More Flash Like Web?
 
Nodejs and WebSockets
Nodejs and WebSocketsNodejs and WebSockets
Nodejs and WebSockets
 
Protocol-Oriented Programming in Swift
Protocol-Oriented Programming in SwiftProtocol-Oriented Programming in Swift
Protocol-Oriented Programming in Swift
 
An Introduction To jQuery
An Introduction To jQueryAn Introduction To jQuery
An Introduction To jQuery
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?HTML5 - Daha Flash bir web?
HTML5 - Daha Flash bir web?
 
NodeJS
NodeJSNodeJS
NodeJS
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
 
Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)Node.js vs Play Framework (with Japanese subtitles)
Node.js vs Play Framework (with Japanese subtitles)
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
Intro to JavaFX & Widget FX
Intro to JavaFX & Widget FXIntro to JavaFX & Widget FX
Intro to JavaFX & Widget FX
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
huhu
huhuhuhu
huhu
 

Mais de Saúl Ibarra Corretgé

Challenges running Jitsi Meet at scale during the pandemic
Challenges running Jitsi Meet at scale during the pandemicChallenges running Jitsi Meet at scale during the pandemic
Challenges running Jitsi Meet at scale during the pandemicSaúl Ibarra Corretgé
 
The Road to End-to-End Encryption in Jitsi Meet
The Road to End-to-End Encryption in Jitsi MeetThe Road to End-to-End Encryption in Jitsi Meet
The Road to End-to-End Encryption in Jitsi MeetSaúl Ibarra Corretgé
 
Jitsi Meet: our tale of blood, sweat, tears and love
Jitsi Meet: our tale of blood, sweat, tears and loveJitsi Meet: our tale of blood, sweat, tears and love
Jitsi Meet: our tale of blood, sweat, tears and loveSaúl Ibarra Corretgé
 
Jitsi Meet: Video conferencing for the privacy minded
Jitsi Meet: Video conferencing for the privacy mindedJitsi Meet: Video conferencing for the privacy minded
Jitsi Meet: Video conferencing for the privacy mindedSaúl Ibarra Corretgé
 
Get a room! Spot: the ultimate physical meeting room experience
Get a room! Spot: the ultimate physical meeting room experienceGet a room! Spot: the ultimate physical meeting room experience
Get a room! Spot: the ultimate physical meeting room experienceSaúl Ibarra Corretgé
 
Going Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTCGoing Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTCSaúl Ibarra Corretgé
 
Going Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTCGoing Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTCSaúl Ibarra Corretgé
 
Jitsi: state-of-the-art video conferencing you can self-host
Jitsi: state-of-the-art video conferencing you can self-hostJitsi: state-of-the-art video conferencing you can self-host
Jitsi: state-of-the-art video conferencing you can self-hostSaúl Ibarra Corretgé
 
WebRTC: El epicentro de la videoconferencia y IoT
WebRTC: El epicentro de la videoconferencia y IoTWebRTC: El epicentro de la videoconferencia y IoT
WebRTC: El epicentro de la videoconferencia y IoTSaúl Ibarra Corretgé
 

Mais de Saúl Ibarra Corretgé (15)

Challenges running Jitsi Meet at scale during the pandemic
Challenges running Jitsi Meet at scale during the pandemicChallenges running Jitsi Meet at scale during the pandemic
Challenges running Jitsi Meet at scale during the pandemic
 
The Road to End-to-End Encryption in Jitsi Meet
The Road to End-to-End Encryption in Jitsi MeetThe Road to End-to-End Encryption in Jitsi Meet
The Road to End-to-End Encryption in Jitsi Meet
 
Jitsi: State of the Union 2020
Jitsi: State of the Union 2020Jitsi: State of the Union 2020
Jitsi: State of the Union 2020
 
Jitsi Meet: our tale of blood, sweat, tears and love
Jitsi Meet: our tale of blood, sweat, tears and loveJitsi Meet: our tale of blood, sweat, tears and love
Jitsi Meet: our tale of blood, sweat, tears and love
 
Jitsi Meet: Video conferencing for the privacy minded
Jitsi Meet: Video conferencing for the privacy mindedJitsi Meet: Video conferencing for the privacy minded
Jitsi Meet: Video conferencing for the privacy minded
 
Jitsi - Estado de la unión 2019
Jitsi - Estado de la unión 2019Jitsi - Estado de la unión 2019
Jitsi - Estado de la unión 2019
 
Get a room! Spot: the ultimate physical meeting room experience
Get a room! Spot: the ultimate physical meeting room experienceGet a room! Spot: the ultimate physical meeting room experience
Get a room! Spot: the ultimate physical meeting room experience
 
Going Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTCGoing Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTC
 
Going Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTCGoing Mobile with React Native and WebRTC
Going Mobile with React Native and WebRTC
 
Jitsi: Estado de la Unión (2018)
Jitsi: Estado de la Unión (2018)Jitsi: Estado de la Unión (2018)
Jitsi: Estado de la Unión (2018)
 
Jitsi: state-of-the-art video conferencing you can self-host
Jitsi: state-of-the-art video conferencing you can self-hostJitsi: state-of-the-art video conferencing you can self-host
Jitsi: state-of-the-art video conferencing you can self-host
 
WebRTC: El epicentro de la videoconferencia y IoT
WebRTC: El epicentro de la videoconferencia y IoTWebRTC: El epicentro de la videoconferencia y IoT
WebRTC: El epicentro de la videoconferencia y IoT
 
Jitsi: Open Source Video Conferencing
Jitsi: Open Source Video ConferencingJitsi: Open Source Video Conferencing
Jitsi: Open Source Video Conferencing
 
Extendiendo SIP con WebRTC
Extendiendo SIP con WebRTCExtendiendo SIP con WebRTC
Extendiendo SIP con WebRTC
 
De SIP a WebRTC y vice versa
De SIP a WebRTC y vice versaDe SIP a WebRTC y vice versa
De SIP a WebRTC y vice versa
 

Último

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 

Último (20)

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 

Python, WebRTC and You (v2)

  • 1. Python, WebRTC and You Saúl Ibarra Corretgé
 @saghul v2
  • 4. Have you ever used it?
  • 6. What is WebRTC? WebRTC (Web Real-Time Communication) is an API definition drafted by the World Wide Web Consortium (W3C) that supports browser-to-browser applications for voice calling, video chat, and P2P file sharing without the need of either internal or external plugins.
  • 7.
  • 8.
  • 9.
  • 11. You need an adapter Implementation in browsers is currently inconsistent Some APIs are still in flux
  • 13. Temasys WebRTC Plugin Free (as in beer) plugin for IE and Safari http://skylink.io/plugin/
  • 15. getUserMedia if (!rtcninja.hasWebRTC()) { console.log('Are you from the past?!'); return; } ! rtcninja.getUserMedia( // constraints {video: true, audio: true}, ! // successCallback function(localMediaStream) { var video = document.querySelector('video'); rtcninja.attachMediaStream(video, localMediaStream); }, ! // errorCallback function(err) { console.log("The following error occured: " + err); } );
  • 16.
  • 17. RTCPeerConnection Handles streaming of media between 2 peers Uses state of the art technology JSEP
  • 18. RTCPeerConnection (2) Get local media Send SDP offer Get local media Send SDP answer ICE candidates Audio / Video
  • 20. ICE Helps find the best path for media Solves NAT traversal and other hostile network problems Communication Consent Verification It can trickle!
  • 21.
  • 22. What about the signalling? It’s not specified! Use SIP, XMPP or roll your own!
  • 23.
  • 24.
  • 25. RTCDataChannel P2P, message boundary based channel for arbitrary data Implemented using SCTP, different reliability choices possible
  • 26.
  • 29. The Protocol WebSocket based, JSON payload Users enter the roulette when they connect over WebSocket Session is negotiated / established No end message, just disconnect the WebSocket
  • 33. {'jsep': {'sdp': '...', 'type': 'offer'}, 'yo': 'yo'}
  • 34. {'jsep': {'sdp': '...', 'type': 'answer'}, 'yo': 'yo'}
  • 36.
  • 37. Shopping for a framework Python >= 3.3, because future! WebSocket support built-in Async, because blocking is so 2001 New, because why not?
  • 40. @asyncio.coroutine def init(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/', LazyFileHandler(INDEX_FILE, 'text/html')) app.router.add_route('GET', '/ws', WebSocketHandler()) app.router.add_route('GET', '/static/{path:.*}', StaticFilesHandler(STATIC_FILES)) ! handler = app.make_handler() server = yield from loop.create_server(handler, '0.0.0.0', 8080) print("Server started at http://0.0.0.0:8080") return server, handler
  • 41. class StaticFilesHandler: def __init__(self, base_path): self.base_path = base_path self.cache = {} ! @asyncio.coroutine def __call__(self, request): path = request.match_info['path'] try: data, content_type = self.cache[path] except KeyError: full_path = os.path.join(self.base_path, path) try: with open(full_path, 'rb') as f: content_type, encoding = mimetypes.guess_type(full_path, strict=False) data = f.read() except IOError: log.warning('Could not open %s file' % path) raise web.HTTPNotFound() self.cache[path] = data, content_type log.debug('Loaded file %s (%s)' % (path, content_type)) return web.Response(body=data, content_type=content_type)
  • 42. class WebSocketHandler: def __init__(self): self.waiter = None ! @asyncio.coroutine def __call__(self, request): ws = web.WebSocketResponse(protocols=('callroulette-v2',)) ws.start(request) ! conn = Connection(ws) if self.waiter is None: self.waiter = asyncio.Future(loop=ws._loop) fs = [conn.read(), self.waiter] done, pending = yield from asyncio.wait(fs, return_when=asyncio.FIRST_COMPLETED) if self.waiter not in done: # the connection was most likely closed self.waiter = None return ws other = self.waiter.result() self.waiter = None reading_task = pending.pop()
 reading_task.cancel() asyncio.async(self.run_roulette(conn, other)) else: self.waiter.set_result(conn) ! yield from conn.wait_closed() ! return ws
  • 43. from jsonmodels import models, fields from jsonmodels.errors import ValidationError ! ! class StringChoiceField(fields.StringField): def __init__(self, choices=None, *args, **kw): self.choices = choices or [] super(StringChoiceField, self).__init__(*args, **kw) ! def validate(self, value): if value not in self.choices: raise ValidationError('invalid choice value') super(StringChoiceField, self).validate(value) ! class Jsep(models.Base): type = StringChoiceField(choices=['offer', 'answer'], required=True) sdp = fields.StringField(required=True) ! class Candidate(models.Base): candidate = fields.StringField(required=True) sdpMid = fields.StringField(required=True) sdpMLineIndex = fields.IntField(required=True) ! class YoPayload(models.Base): yo = fields.StringField(required=True) jsep = fields.EmbeddedField(Jsep) candidate = fields.EmbeddedField(Candidate)
  • 44. @asyncio.coroutine def run_roulette(self, peerA, peerB): log.info('Running roulette: %s, %s' % (peerA, peerB)) ! @asyncio.coroutine def close_connections(): yield from asyncio.wait([peerA.close(), peerB.close()],
 return_when=asyncio.ALL_COMPLETED) ! def parse(data): try: data = json.loads(data) payload = YoPayload(**data) payload.validate() except Exception as e: log.warning('Error parsing payload: %s' % e) return None return payload
  • 45. # request offer offer_request = YoPayload(yo='yo') peerA.write(json.dumps(offer_request.to_struct())) ! # get offer data = yield from peerA.read(timeout=READ_TIMEOUT) if not data: yield from close_connections() return ! offer = parse(data) if offer is None or offer.jsep is None or offer.jsep.type != 'offer': log.warning('Invalid offer received') yield from close_connections() return ! # send offer peerB.write(json.dumps(offer.to_struct()))
  • 46. # wait for answer data = yield from peerB.read(timeout=READ_TIMEOUT) if not data: yield from close_connections() return ! answer = parse(data) if answer is None or answer.jsep is None or answer.jsep.type != 'answer': log.warning('Invalid answer received') yield from close_connections() return ! # dispatch answer peerA.write(json.dumps(answer.to_struct()))
  • 47. # wait for candidates / end while True: peer_a_read = asyncio.async(peerA.read()) peer_a_read.other_peer = peerB peer_b_read = asyncio.async(peerB.read()) peer_b_read.other_peer = peerA done, pending = yield from asyncio.wait([peer_a_read, peer_b_read], return_when=asyncio.FIRST_COMPLETED) for task in pending: task.cancel() for task in done: data = task.result() if not data: break # all we can get at this point is trickled ICE candidates candidate = parse(data) if candidate is None or candidate.candidate is None: log.warning('Invalid candidate received!') break task.other_peer.write(json.dumps(candidate.to_struct())) else: continue break # close connections yield from close_connections()
  • 48.