2. About me
● WEB developer since 2009
● Symfony developer at SmartGamma
since 2013
● https://github.com/stas-zozulja
● https://www.facebook.com/stas.zozulj
a
Real-Time Web applications with Websocket
3. Real-Time Web applications with Websocket
Agenda
● What is Real-Time Web?
● Transport mechanisms
● Real-Time in PHP (Ratchet)
● && everywhere (Pushpin)
4. 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
5. 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
6. Do I need real-time?
YES! You do!
● Better UX - instant data updates
● Chatting, notification, signaling
● Activity streams
● Data visualization
● User collaboration
8. Long polling
Delayed HTTP request. After response (or timeout)
new request is opening by client.
● Uni-directional
● Overhead
(headers in each request)
9. HTTP Streaming
Request that never ends, response content is
chunked in portions, usually JSON. Only one
direction.
16. & Step 3. Write Console command that runs a server
17. & Next steps. WAMP Subprotocol.
● WAMP – Web Application Messaging
Protocol.
● RPC and Pub/Sub patterns
● Autobahn client libraries
http://wamp-proto.org/
http://autobahn.ws/
18. &
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
21. Pushpin
a 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/
23. 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/wiki
https://github.com/fanout/pushpin/blob/master/docs/websocket-over-http.md
24. 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 message
TEXT, BINARY – content messages
PING, PONG – ping/pong messages
CLOSE - Close message with 16-bit close code
DISCONNECT - Indicates connection closed uncleanly
25. 1. From client to Pushpin (port 7999):
GET /chat HTTP/1.1
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: T6IDGBEmb...
Connection: Upgrade
Upgrade: websocket
2. From Pushpin to backend:
POST /chat HTTP/1.1
Sec-WebSocket-Extensions: grip
Content-Type:
application/websocket-events
Accept:
application/websocket-events
OPENrn
2. Response:
HTTP/1.1 200 OK
Sec-WebSocket-Extensions: grip
Content-Type:
application/websocket-events
OPENrn
WebSocket over HTTP connection flow
3. Form Pushpin to client:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBi...
Sec-WebSocket-Extensions: grip
26. 1. From client to Pushpin (port 7999):
//sending message
WebSocket.send(“Hello there! I’m client!”);
2. From Pushpin to backend:
POST /chat HTTP/1.1
Sec-WebSocket-Extensions: grip
Content-Type:
application/websocket-events
Accept:
application/websocket-events
TEXT 18rn
Hello there! I’m client!
2. Response:
HTTP/1.1 200 OK
Sec-WebSocket-Extensions: grip
Content-Type:
application/websocket-events
TEXT 12rn
Hello! I’m server!
TEXT 2Frn
c:{"type": "subscribe", "channel":
"mychannel"}rn
WebSocket over HTTP message flow
3. On client:
//receiving message
WebSocket.onMesssage(event) …
//event.data is “Hello! I’m server!”
27. PublishSubscribe. 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
28. 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
theren"
}
}
}
]
}' http://localhost:5561/publish/
29. 1. From client to Pushpin:
GET /chat HTTP/1.1
Sec-WebSocket-Version: 13
Sec-WebSocket-Key:
T6IDGBEmb...
Connection: Upgrade
Upgrade: websocket
2. Request:
POST /chat HTTP/1.1
Sec-WebSocket-Extensions: grip
Content-Type:
application/websocket-
events
Accept:
application/websocket-
events
OPENrn
2. Response:
HTTP/1.1 200 OK
Sec-WebSocket-Extensions: grip
Content-Type:
application/websocket-
events
OPENrn
So, all we need is to handle Requests from Pushpin
in our application. A GOOD job for Symfony, isn't it?
3. Form Pushpin to client:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBi...
Sec-WebSocket-Extensions: grip
30. PHP Library to work with Pushpin on server side
composer require fanout/gripcontrol
https://github.com/fanout/php-
gripcontrol
32. 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.