changed 6 years ago
Published Linked with GitHub

How-to: Make your application real-time

https://hackmd.io/p/parisjs-realtime


We'll invite you to play with us!
Get ready to join with your phone or laptop.


Join the Demo!

https://hackmd.io/parisjs-realtime-demo


HackMD

Build community with open collaboration



Techstars backed


Helping developers to enjoy writing documentations.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Help open source technologies to build an active developer community.


Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Max Wu

CTO of HackMD

I love great product and build them.
I'm developing my dream with code.


What is real-time?

Enable users to receive information as soon as it is published by its authors.



How fast will you consider it's real-time?

60 FPS makes a smooth video.

60 frames per second (FPS)

1000 millisecond / 60 frames
~= 16.67 ms/frame


16.67 ms

for such a computation


The average network latency is
70 ms



Hard to feel it's real-time

if it only shows when data arrives


So you fake it!
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

that's what most modern web app does


Optimistic lock

  • Show as soon as user inputs it
  • Put the operation into buffer and send later
  • Rollback if it fails later

What makes web real-time?

  • You need to connect network
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • So that server can receive your changes
  • And other clients are able to receive updates
  • Let's see how HTTP works

traditional HTTP model

  1. client sends request to server
  2. server responses data to client


It's one way communication

server can't actively push data to client

real-time requires to send updates to client

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


long-polling HTTP model

  1. client sends request to server
  2. keeps the connection open
  3. client waits until server sends data


Still one way communication

  • But it works!
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
    (and for a long time)
  • HTTP 1.1 is half-duplex,
    traffic flows only go one direction at a time
  • HTTP is stateless,
    reduntant information sent with every request and response

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


WebSocket comes to rescue!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


WebSocket

  • bidirectional communication
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • smaller data frame (~1/3 than HTTP)
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • lower latency (~4x faster than HTTP)
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

ref.



Efficiency

HTTP WebSocket
Overhead 100s bytes 2-6 bytes
Latency (traditional) New connection every time None: use existing connection
Latency (long-polling) Time to set up next request No waiting

ref.


What can you build with WebSocket?

see some examples


Collaborative text editor

HackMD

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
https://hackmd.io
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Agar.io

An online multipleplayer game


Online chat room

https://socketio-chat-example.now.sh/


GitHub

also uses it to update pages

  • When other people comment on the issue
  • When issue has been closed
  • When pull request have more commits
  • etc

There's always a catch


https://caniuse.com/#search=websocket


Time for Socket.IO
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Socket.IO
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  1. Establishes long-polling connection first
  2. Tries to upgrade to WebSocket transports
  3. If it fails will fallback to use long-polling

Everyone now is happy

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Socket.IO
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • Intuitive APIs
  • Easy to broadcast multiple clients
  • Built-in logic for rooms and namespaces

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →


Let's make a chat room with Socket.IO


Installation

Client

<script src="/socket.io/socket.io.js"></script>

Include socket.io-client script in the html.


Installation

Server

npm install --save socket.io

Install socket.io from npm

const server = require('http').createServer() const io = require('socket.io')(server) server.listen(3000)

Create HTTP server and bind with socket.io in the node.js app.


Client establishes connection

const socket = io()

Client tries to connect chat room


Server listens on connection

io.on('connection', socket => { console.log('a user connected') socket.on('disconnect', () => { console.log('user disconnected') }) })

Server accepts client connection


Server broadcasts to everyone

io.emit('room message', 'room is ready')

Server broadcasts room status


Client emits event

socket.emit('chat message', 'hello world!')

Client emits chat message to room


Server listens on event

socket.on('chat message', msg => { console.log('message: ' + msg) })

Server receives the message


Server sends to everyone

excepts for a certain socket

io.on('connection', socket => { socket.on('chat message', msg => { console.log('message: ' + msg) socket.broadcast.emit(msg) }) })

Server broadcasts chat message to other clients

read more
emit cheatsheet



Server-Sent Events

an alternative for sending from server to client


Server-Sent Events

  • It's one way - server pushes to client
  • Part of HTML5 standard
  • Good with HTTP/2 (which is full-duplex)
  • Automatic reconnection and event binding


There's always a catch, again


Can be easily polyfilled!
https://caniuse.com/#search=server sent


Comparsion

HTTP WebSocket SSE
Direction Client to Server Bidirectional Server to Client
Native support 100% 90% 84%
Overhead High Low Medium
Latency 1-2s < 1s 1s

TL;DR

  • You can fake the real-time experience
  • long-polling is the old way to be real-time
  • WebSocket is the real bidirectional communication
  • Socket.IO is the one for all
  • Server-Sent Events with HTTP/2 can be an alternative

Thanks for listening!

Do you have any question?

@jackycute

HackMD.io


References


References

Select a repo