Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

102
Symfony2, Backbone.js & socket.io Symfony live Paris 2013 @guillaumepotier [email protected]

description

Wisembly experience sharing on building one-page js app w/ Backbone.js over Symfony2 REST API and socket.io push server.

Transcript of Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

Page 1: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

Symfony2, Backbone.js & socket.io

Symfony live Paris 2013

@[email protected]

Page 2: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

app.wisembly.com/sflive

Page 3: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

2011, September

Page 4: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PHP

MySQL

Page 5: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PHP

MySQL

Doctrine 2

Symfony 2

Twig

Page 6: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PHP

MySQL

Doctrine 2

Symfony 2

Twig

jQuery

Twig js

Assetic

Page 7: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PHP

MySQL

Doctrine 2

Symfony 2

Twig

jQuery

Twig js

Assetic

Underscore.js

Backbone.js

Page 8: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PHP

MySQL

Doctrine 2

Symfony 2

Twig

jQuery

Twig js

Assetic

Underscore.js

Backbone.js

TOO MUCH!

Page 9: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Client

Server

Page 10: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Client

Server

PHP

MySQL

Doctrine 2

Symfony 2

Twig REST

Page 11: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Client

Server

PHP

MySQL

Doctrine 2

Symfony 2

Twig

HTML

jQuery

Underscore.js

Backbone.js

REST

Page 12: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Client

Server

PHP

MySQL

Doctrine 2

Symfony 2

Twig

HTML

jQuery

Underscore.js

Backbone.js

RESTLONG POLLING!

Page 13: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Users want fast & smooth SaaS apps

Page 14: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Users want fast & smooth SaaS appsUsers want multiplateform SaaS apps

Page 15: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Users want fast & smooth SaaS appsUsers want multiplateform SaaS apps

Users want dynamic & interactive SaaS apps

Page 16: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Users want fast & smooth SaaS appsUsers want multiplateform SaaS apps

Users want dynamic & interactive SaaS apps

You should do so!

Page 17: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Users want fast & smooth SaaS appsUsers want multiplateform SaaS apps

Users want dynamic & interactive SaaS apps

You should do so!

BUT HOW?

Page 18: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Page 19: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

?

Page 20: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

HELL

NO!?

Page 21: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Page 22: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Nowadays

Page 23: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Page 24: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

small / lightweight / stable

Page 25: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

small / lightweight / stable

easy to learn, easy to extend

Page 26: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

small / lightweight / stable

easy to learn, easy to extend

great resources:

layoutManager

relational

Page 27: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Models Models

Page 28: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Models Models

Collections Repositories

Page 29: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Models Models

Collections Repositories

Views Controllers

Page 30: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Models Models

Collections Repositories

Views Controllers

Templates Views

Page 31: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Models Models

Collections Repositories

Views Controllers

Templates Views

Routing Routing

Page 32: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Models Models

Collections Repositories

Views Controllers

Templates Views

Routing RoutingREST + PUSH

Page 33: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

BazingaExposeTranslationFOSJsRouting

FOSRestBundleJMSSerializer

Page 34: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

BazingaExposeTranslationFOSJsRouting

FOSRestBundleJMSSerializer

Page 35: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

1 - MAKE AN API

Page 37: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Books = new Backbone.collection();Books.url = ‘/books’;

@nacmarti

n

Page 38: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Books = new Backbone.collection();Books.url = ‘/books’;

GET /books

Books.fetch();

@nacmarti

n

Page 39: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

events: { ‘click .mybutton’:‘doStuffAndSave’ }

doStuffAndSave: function() {var book = Books.get(3);book.stuff();book.save();

}

@nacmarti

n

Page 40: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

events: { ‘click .mybutton’:‘doStuffAndSave’ }

doStuffAndSave: function() {var book = Books.get(3);book.stuff();book.save();

}

PUT /books/3

@nacmarti

n

Page 41: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

[ {“id”:1,

“name”:”guillaume”, “phone”: “0611010011”

...

}, {...},]

/** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id;

/** * @var string $name * * @ORM\Column(name="name", type="string", length=50, nullable=true) */ private $name;

/** * @var string $phone * * @ORM\Column(name="phone", type="string", length=20, nullable=true) */ private $phone;

...

Page 42: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

II - MAKE A GOOD REST API

Page 44: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

JMSSerializer

or

Page 45: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

class User implements UserInterface, EquatableInterface, ApiAbleInterface{

}

JMSSerializer

or

Page 46: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

public function toArray(){ return [ 'id' => $this->getId(), 'name' => $this->getName(), 'email' => $this->getEmail(), ];}

class User implements UserInterface, EquatableInterface, ApiAbleInterface{

}

JMSSerializer

or

Page 47: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

FOSRestBundle

or

Page 48: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("{keyword}/quote/{id}", name="api3_quote_get", options={"expose"=true}) * @Method({"GET", "OPTIONS"}) */ public function getQuote(EventInterface $event, $id) { try { $quote = $this->get('api3.quote')->get($id); return $this->container->get('api3.response')->newSuccessResponse($quote->toArray(), 200); } catch (NoResultException $e) { return $this->container->get('api3.response')->newErrorResponse('No quote found', ErrorCode::NO_QUOTE, 404); } }

FOSRestBundle

or

Page 49: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("{keyword}/quote/{id}", name="api3_quote_get", options={"expose"=true}) * @Method({"GET", "OPTIONS"}) */ public function getQuote(EventInterface $event, $id) { try { $quote = $this->get('api3.quote')->get($id); return $this->container->get('api3.response')->newSuccessResponse($quote->toArray(), 200); } catch (NoResultException $e) { return $this->container->get('api3.response')->newErrorResponse('No quote found', ErrorCode::NO_QUOTE, 404); } }

FOSRestBundle

or

Page 50: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("{keyword}/quote/{id}", name="api3_quote_get", options={"expose"=true}) * @Method({"GET", "OPTIONS"}) */ public function getQuote(EventInterface $event, $id) { try { $quote = $this->get('api3.quote')->get($id); return $this->container->get('api3.response')->newSuccessResponse($quote->toArray(), 200); } catch (NoResultException $e) { return $this->container->get('api3.response')->newErrorResponse('No quote found', ErrorCode::NO_QUOTE, 404); } }

FOSRestBundle

or

Page 51: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("{keyword}/quote/{id}", name="api3_quote_get", options={"expose"=true}) * @Method({"GET", "OPTIONS"}) */ public function getQuote(EventInterface $event, $id) { try { $quote = $this->get('api3.quote')->get($id); return $this->container->get('api3.response')->newSuccessResponse($quote->toArray(), 200); } catch (NoResultException $e) { return $this->container->get('api3.response')->newErrorResponse('No quote found', ErrorCode::NO_QUOTE, 404); } }

FOSRestBundle

or

Page 52: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("{keyword}/quote/{id}", name="api3_quote_get", options={"expose"=true}) * @Method({"GET", "OPTIONS"}) */ public function getQuote(EventInterface $event, $id) { try { $quote = $this->get('api3.quote')->get($id); return $this->container->get('api3.response')->newSuccessResponse($quote->toArray(), 200); } catch (NoResultException $e) { return $this->container->get('api3.response')->newErrorResponse('No quote found', ErrorCode::NO_QUOTE, 404); } }

FOSRestBundle

or

Page 53: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("{keyword}/quote/{id}", name="api3_quote_get", options={"expose"=true}) * @Method({"GET", "OPTIONS"}) */ public function getQuote(EventInterface $event, $id) { try { $quote = $this->get('api3.quote')->get($id); return $this->container->get('api3.response')->newSuccessResponse($quote->toArray(), 200); } catch (NoResultException $e) { return $this->container->get('api3.response')->newErrorResponse('No quote found', ErrorCode::NO_QUOTE, 404); } }

FOSRestBundle

or

Page 54: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("{keyword}/quote/{id}", name="api3_quote_get", options={"expose"=true}) * @Method({"GET", "OPTIONS"}) */ public function getQuote(EventInterface $event, $id) { try { $quote = $this->get('api3.quote')->get($id); return $this->container->get('api3.response')->newSuccessResponse($quote->toArray(), 200); } catch (NoResultException $e) { return $this->container->get('api3.response')->newErrorResponse('No quote found', ErrorCode::NO_QUOTE, 404); } }

FOSRestBundle

or

Page 55: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Entity EntityRepository

Entity Service

Controller

API Service

Page 56: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

<?php

// ...

private function processForm(User $user) {

$form = $this->createForm(new UserType(), $user); $form->bind($this->getRequest());

if ($form->isValid()) {

$this->doYourStuff(); return $user; }

// ...

}

Use Validator and Form

@couac

Page 57: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("event/{keyword}/poll/{id}", name="api3_poll_edit", requirements={"id" = "\d+"}, options={"expose"=true}) * @Method({"POST", "PUT", "OPTIONS"}) */ public function editPollAction(EventInterface $event, Request $request, $id) { try {

$poll = $this->get('api3.poll')->get($event, $id);

$poll = $this->get('api3.poll')->edit($poll, $request);

return $this->container->get('api3.response')->newSuccessResponse($poll->toArray(), 201);

} catch (NoResultException $e) {// ... } catch (AccessDeniedException $e) {// ... } catch (\Exception $e) {// ... } }

Page 58: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("event/{keyword}/poll/{id}", name="api3_poll_edit", requirements={"id" = "\d+"}, options={"expose"=true}) * @Method({"POST", "PUT", "OPTIONS"}) */ public function editPollAction(EventInterface $event, Request $request, $id) { try {

$poll = $this->get('api3.poll')->get($event, $id);

$poll = $this->get('api3.poll')->edit($poll, $request);

return $this->container->get('api3.response')->newSuccessResponse($poll->toArray(), 201);

} catch (NoResultException $e) {// ... } catch (AccessDeniedException $e) {// ... } catch (\Exception $e) {// ... } }

Page 59: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("event/{keyword}/poll/{id}", name="api3_poll_edit", requirements={"id" = "\d+"}, options={"expose"=true}) * @Method({"POST", "PUT", "OPTIONS"}) */ public function editPollAction(EventInterface $event, Request $request, $id) { try {

$poll = $this->get('api3.poll')->get($event, $id);

$poll = $this->get('api3.poll')->edit($poll, $request);

return $this->container->get('api3.response')->newSuccessResponse($poll->toArray(), 201);

} catch (NoResultException $e) {// ... } catch (AccessDeniedException $e) {// ... } catch (\Exception $e) {// ... } }

Page 60: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("event/{keyword}/poll/{id}", name="api3_poll_edit", requirements={"id" = "\d+"}, options={"expose"=true}) * @Method({"POST", "PUT", "OPTIONS"}) */ public function editPollAction(EventInterface $event, Request $request, $id) { try {

$poll = $this->get('api3.poll')->get($event, $id);

$poll = $this->get('api3.poll')->edit($poll, $request);

return $this->container->get('api3.response')->newSuccessResponse($poll->toArray(), 201);

} catch (NoResultException $e) {// ... } catch (AccessDeniedException $e) {// ... } catch (\Exception $e) {// ... } }

Page 61: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

/** * @Route("event/{keyword}/poll/{id}", name="api3_poll_edit", requirements={"id" = "\d+"}, options={"expose"=true}) * @Method({"POST", "PUT", "OPTIONS"}) */ public function editPollAction(EventInterface $event, Request $request, $id) { try {

$poll = $this->get('api3.poll')->get($event, $id);

$poll = $this->get('api3.poll')->edit($poll, $request);

return $this->container->get('api3.response')->newSuccessResponse($poll->toArray(), 201);

} catch (NoResultException $e) {// ... } catch (AccessDeniedException $e) {// ... } catch (\Exception $e) {// ... } }

Page 62: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Page 63: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Page 64: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

BazingaExposeTranslationFOSJsRouting

FOSRestBundleJMSSerializer

Page 65: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

events: {‘bookUpdated’:‘update’,‘bookCreated’: ‘create’,‘bookDeleted’:‘delete’,

}

update: function(websocketData) {doStuff(websocketData);

},create: function(websocketData) {

doOtherStuff(websocketData);},delete: function(websocketData) {

stillDoOtherStuff(websocketData);}

@nacmarti

n

Page 66: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

events: {‘bookUpdated’:‘update’,‘bookCreated’: ‘create’,‘bookDeleted’:‘delete’,

}

update: function(websocketData) {doStuff(websocketData);

},create: function(websocketData) {

doOtherStuff(websocketData);},delete: function(websocketData) {

stillDoOtherStuff(websocketData);}

FULL EVENT BASEDREAL TIME

@nacmarti

n

Page 67: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

websocketData?

Who sends what?

Which port, which protocol?

Page 68: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Page 69: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

BazingaExposeTranslationFOSJsRouting

FOSRestBundleJMSSerializer

Page 70: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Authenticate user againstPUSH server

Page 71: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

sessionTokendomain

Authenticate user againstPUSH server

Page 72: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

sessionTokendomain

RESTsessionToken

domain

Authenticate user againstPUSH server

Page 73: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

sessionTokendomain

REST

rights

sessionTokendomain

Authenticate user againstPUSH server

Page 74: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

REST

rights

sessionTokendomain

Authenticated!

Authenticate user againstPUSH server

Page 75: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Classic» way

rights

Page 76: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Classic» way

RESTsessionToken

domain

rights

Page 77: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Classic» way

RESTsessionToken

domaindata

rights

Page 78: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Classic» way

RESTsessionToken

domaindata

rights

Page 79: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Classic» way

RESTsessionToken

domaindata

websocketData

rights

Page 80: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

• Slow: HTTP ajax round-trip

• !DRY: Double front processing (Ajax / Push)

• Push server complexity: authorizations

Page 81: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Wisembly» way

RESTsessionToken

domaindata

websocketData

rights

Page 82: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Wisembly» way

RESTsessionToken

domain

websocketData

websocketData

rightssecret

Page 83: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Wisembly» way

RESTsessionToken

domain

websocketData

websocketData

websocketData

rightssecret

Page 84: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

PUSH: The «Wisembly» way

RESTsessionToken

domaindata

websocketData

websocketData

websocketData

rightssecret

Page 85: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Push «surprises»

Page 86: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Push «surprises»

• Must find always opened port

Page 87: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Push «surprises»

• Must find always opened port

• Websocket protocol must go through firewalls

Page 88: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Push «surprises»

• Must find always opened port

• Websocket protocol must go through firewalls

• Push may disconnect (very!) frequently and loose events (duh!)

Page 89: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Page 90: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

• 80 always opened, but websocket very often blocked -> FAIL -> goto 443 w/ https

Page 91: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

• 80 always opened, but websocket very often blocked -> FAIL -> goto 443 w/ https

• Implement disconnection mechanism and lost events in case of socket.io «degraded» protocol (xhr polling, jsonp polling)

Page 92: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

The «Wisembly» way

hashN: { eventName, args }

Page 93: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

The «Wisembly» way

hashN: { eventName, args }

Page 94: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

The «Wisembly» way

hash1: { eventName, args }hash2: { eventName, args }

...hashN: { eventName, args }

hashN: { eventName, args }

hashN: { eventName, args }

hashN: { eventName, args }

hashN

hashN hashN

Page 95: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

The «Wisembly» way

hashN: { eventName, args }...

hashN+M: { eventName, args }

hashN

hashM hashM

Page 96: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

The «Wisembly» way

hashN: { eventName, args }...

hashN+M: { eventName, args }

hashNRESTonReconect()since hashN

hashM hashM

Page 97: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

The «Wisembly» way

hashN: { eventName, args }...

hashN+M: { eventName, args }

hashNRESTonReconect()since hashN

hashN+1: { eventName, args }...

hashN+M: { eventName, args }

hashM hashM

Page 98: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

The «Wisembly» way

hashN: { eventName, args }...

hashN+M: { eventName, args }

RESTonReconect()since hashN

hashN+1: { eventName, args }...

hashN+M: { eventName, args }

hashM hashM

hashM

Page 101: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive

Any Questions ?

Page 102: Symfony2, Backbone.js & socket.io - SfLive Paris 2k13 - Wisembly

app.wisembly.com/sflive