41
Stas Zozulja stas.z@smart- gamma.com Real-Time Web applications with WebSockets

Real-Time Web applications with WebSockets

Embed Size (px)

Citation preview

Page 1: Real-Time Web applications with WebSockets

Stas [email protected]

Real-Time Web applications with WebSockets

Page 2: Real-Time Web applications with WebSockets

About me

● WEB developer since 2009

● Symfony developer at SmartGamma since 2013

● https://github.com/stas-zozulja

● https://www.facebook.com/stas.zozulja

Real-Time Web applications with Websocket

Page 3: Real-Time Web applications with WebSockets

Real-Time Web applications with Websocket

Agenda

● What is Real-Time Web?● Transport mechanisms● Real-Time in PHP (Ratchet)● && everywhere (Pushpin)

Page 4: Real-Time Web applications with WebSockets

What is Real-Time ?

https://www.leggetter.co.uk/2016/04/22/what-is-realtime.html

● Hard real-time- missed deadline?

System fault● Firm real-time

- missed? Result is zero

● Soft real-time- missed?

quality degrades

it's all about deadline

Page 5: Real-Time Web applications with WebSockets

and Real-Time Web?Server pushes a data to Clients when some event occurs, while Clients does not need to poll a server for new data.

it's all about Push

https://www.leggetter.co.uk/2016/04/22/what-is-realtime.html

Page 6: Real-Time Web applications with WebSockets

Do I need real-time?YES! You do!

● Better UX - instant data updates● Chatting, notification, signaling● Activity streams● Data visualization● User collaboration

Page 7: Real-Time Web applications with WebSockets

Transport mechanisms

● Long polling● HTTP streaming● WebSockets

Page 8: Real-Time Web applications with WebSockets

Long pollingDelayed HTTP request. After response (or timeout) new request is opening by client.

● Uni-directional● Overhead

(headers in each request)

Page 9: Real-Time Web applications with WebSockets

HTTP StreamingRequest that never ends, response content is

chunked in portions, usually JSON. Only one direction.

Page 10: Real-Time Web applications with WebSockets

WebSocket protocolProtocol providing bidirectional communication channel over a single TCP connection.

Page 11: Real-Time Web applications with WebSockets

WebSocket handshakeRequest:GET /chat HTTP/1.1Host: ws.example.com:8080/chatSec-WebSocket-Version: 13Sec-WebSocket-Key: T6IDGBEmb...Connection: UpgradeUpgrade: websocket

Response:HTTP/1.1 101 Switching protocolsConnection: UpgradeSec-WebSocket-Accept: xTComwY...Upgrade: websocketX-Powered-By: Ratchet/0.3.4

ws:// wss://

https://tools.ietf.org/html/rfc6455http://caniuse.com/#feat=websockets

Support:● IE 10+● FF 6+● Chrome 14+● iOS 4.2+● Android 4.4+● Safari 5+

Page 12: Real-Time Web applications with WebSockets

Our context● Live streaming app● REST API for mobile clients (iOS, Android)● WEB part● Build Real-time counter of viewers

or

Page 13: Real-Time Web applications with WebSockets

Ratchet - WebSockets for PHP

http://socketo.me/

Built on top of ReactPHP

Components:● I/O (socket transport) – IOServer● HTTP Protocol handler – HTTPServer● WebSocket Protocol Handler – WSServer● SessionProvider – Symfony Session● WAMP Protocol Handler – WampServer

+● Your Application

MessageComponentInterface implementationhttp://reactphp.org/

Page 14: Real-Time Web applications with WebSockets

& Step 1. Implement MessageComponentInterface

Page 15: Real-Time Web applications with WebSockets

& Step 2. onMessage()

Page 16: Real-Time Web applications with WebSockets

& Step 3. Write Console command that runs a server

Page 17: Real-Time Web applications with WebSockets

& Next steps. WAMP Subprotocol.● WAMP – Web Application Messaging

Protocol.● RPC and Pub/Sub patterns● Autobahn client libraries

http://wamp-proto.org/http://autobahn.ws/

Page 18: Real-Time Web applications with WebSockets

&

Cons● Horizontally scaling is hard

need to share a Connections between nodes● One exception can stop whole server

Use supervisord, try...catch, test Your code

Pros● Its PHP!● Easy to implement and use existing code

Page 19: Real-Time Web applications with WebSockets

https://www.leggetter.co.uk/real-time-web-technologies-guide/

j.mp/realtime-tech-guide

Page 20: Real-Time Web applications with WebSockets

https://fanout.io/

Page 21: Real-Time Web applications with WebSockets

Pushpina reverse proxy for the real-time Web

http://pushpin.org/

● Pub/Sub● Long polling, HTTP Streaming or WebSockets● Works with any backend● Your API can be real-time with HTTP streaming● WebSocket over HTTP – what? :)

https://fanout.io/

Page 22: Real-Time Web applications with WebSockets

Pushpin installation

Debian, Ubuntu:sudo apt-get install pushpinsudo service pushpin start

http://pushpin.org/docs/#install

MacOS X:brew install pushpinpushpin

Page 23: Real-Time Web applications with WebSockets

Pushpin configuration

routes config file:* localhost:80,over_http

● route all connections from Pushpin to your backend

● over_http option to enable WebSocket-over-HTTP protocol

https://github.com/fanout/pushpin/wikihttps://github.com/fanout/pushpin/blob/master/docs/websocket-over-http.md

Page 24: Real-Time Web applications with WebSockets

WebSocket-over-HTTP (GRIP protocol)

Pushpin encodes WebSocket events into a regular HTTP requests and passes them to your backend.

Events are:OPEN – opening WebSocket connection messageTEXT, BINARY – content messagesPING, PONG – ping/pong messagesCLOSE - Close message with 16-bit close codeDISCONNECT - Indicates connection closed uncleanly

Page 25: Real-Time Web applications with WebSockets

1. From client to Pushpin (port 7999):GET /chat HTTP/1.1Sec-WebSocket-Version: 13Sec-WebSocket-Key: T6IDGBEmb...Connection: UpgradeUpgrade: websocket

2. From Pushpin to backend:POST /chat HTTP/1.1Sec-WebSocket-Extensions: gripContent-Type: application/websocket-eventsAccept: application/websocket-events

OPEN\r\n

2. Response:HTTP/1.1 200 OKSec-WebSocket-Extensions: gripContent-Type: application/websocket-events

OPEN\r\n

WebSocket over HTTP connection flow

3. Form Pushpin to client:HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBi...Sec-WebSocket-Extensions: grip

Page 26: Real-Time Web applications with WebSockets

1. From client to Pushpin (port 7999)://sending messageWebSocket.send(“Hello there! I’m client!”);

2. From Pushpin to backend:POST /chat HTTP/1.1Sec-WebSocket-Extensions: gripContent-Type: application/websocket-eventsAccept: application/websocket-events

TEXT 18\r\nHello there! I’m client!

2. Response:HTTP/1.1 200 OKSec-WebSocket-Extensions: gripContent-Type: application/websocket-events

TEXT 12\r\nHello! I’m server!TEXT 2F\r\nc:{"type": "subscribe", "channel": "mychannel"}\r\n

WebSocket over HTTP message flow

3. On client://receiving messageWebSocket.onMesssage(event) …

//event.data is “Hello! I’m server!”

Page 27: Real-Time Web applications with WebSockets

Publish\Subscribe. Control messages.

Formatted as a JSON object following the c: prefix. The object has a type field that indicates the type of control message.

● subscribe: Subscribe connection to the channel specified by the channel field.

● unsubscribe: Unsubscribe connection from the channel specified by the channel field.

● detach: Terminate the session between Pushpin and the origin server, but retain the connection between the client and

http://pushpin.org/docs/#websockets

Examples:c:{"type": "subscribe", "channel": "test"}c:{"type": "unsubscribe", "channel": "test"}

Prefix c: is configurable

Page 28: Real-Time Web applications with WebSockets

Publish data to a channel

POST request to a Pushpin’s internal publish port (5561 by default)

curl -d '{"items": [

{ "channel": "test", "formats": {

"ws-message": {"content": "hello there\

n"}

} } ]}' http://localhost:5561/publish/

Page 29: Real-Time Web applications with WebSockets

1. From client to Pushpin:GET /chat HTTP/1.1Sec-WebSocket-Version: 13Sec-WebSocket-Key: T6IDGBEmb...Connection: UpgradeUpgrade: websocket

2. Request:POST /chat HTTP/1.1Sec-WebSocket-Extensions: gripContent-Type:

application/websocket-eventsAccept:

application/websocket-events

OPEN\r\n

2. Response:HTTP/1.1 200 OKSec-WebSocket-Extensions: gripContent-Type:

application/websocket-events

OPEN\r\n

So, all we need is to handle Requests from Pushpinin our application. A GOOD job for Symfony, isn't it?

3. Form Pushpin to client:HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBi...Sec-WebSocket-Extensions: grip

Page 30: Real-Time Web applications with WebSockets

PHP Library to work with Pushpin on server sidecomposer require fanout/gripcontrol

https://github.com/fanout/php-gripcontrol

Page 31: Real-Time Web applications with WebSockets

Publishing from PHP

https://github.com/fanout/php-gripcontrol

Page 32: Real-Time Web applications with WebSockets

Symfony Bundle

https://github.com/smart-gamma/pushpin-bundle

&

Features

● Works with WebSocket-over-HTTP Requests from Pushpin

● TEXT events deserialization into DTOs (events) specified by your configuration

● Handling WebSocketEvent with your specific handler

● Pushpin helpers to publishing to a channel, subscribing, detaching etc.

Page 33: Real-Time Web applications with WebSockets

Live Demo&

http://ws-chat.smart-gamma.com

https://github.com/smart-gamma/simple-chat-demo

Page 34: Real-Time Web applications with WebSockets

Symfony Bundle

$ composer require gamma/pushpin-bundle

# config.ymlgamma_pushpin:

proxy: control_uri: 'http://localhost:5561/'

web_socket: json_events: base_namespace: 'Domain\WebsocketEvents' mappings: chatMessage: class: 'Chat\ChatMessage' chatRoomEnter: class: 'Chat\ChatRoomEnter' chatRoomLeave: class: 'Chat\ChatRoomLeave'

&

Page 35: Real-Time Web applications with WebSockets

Simple DTO object to hold event data&

Page 36: Real-Time Web applications with WebSockets

Implement handler service for your event&

Page 37: Real-Time Web applications with WebSockets

Controller to handle requests from Pushpin&

Page 38: Real-Time Web applications with WebSockets

Test with wscat utility&

Page 39: Real-Time Web applications with WebSockets

&

http://blog.fanout.io/2013/10/30/pushing-to-100000-api-clients-simultaneously/

Pros● It’s still PHP!● No need to run

long lived processes at backend● With HTTP Streaming You can

make a real-time API● Horizontally scalable

Cons● If you have multi nodes,

pushes should be sent to all Pushpin instances

● More HTTP requests to your application

● Push can be sent only to a channel

Page 40: Real-Time Web applications with WebSockets

Load testing with thor utility

Page 41: Real-Time Web applications with WebSockets

Thank You!