Building realtime apps

with react

Hi 👋

I'm Jayden Windle

CTO @ Jetpack

REAltime technologies

REAltime technologies

BUILD a realtime app

REAltime technologies

BUILD a realtime app

Lessons & Next Steps

anY Application that functions within a time frame that the user senses as immediate or current

Chat apps

Uber + Lyft

Analytics dashboards

import React, { useState } from "react";
import daytime from "./daytime.png";
import nighttime from "./nighttime.png";

import "./App.css";

function App() {
  const [isDayTime, setIsDayTime] = useState(true);
  const backgroundColor = isDayTime ? "#efefef" : "#212121";

  return (
    <div className="App" style={{ backgroundColor }}>
      <img
        src={isDayTime ? daytime : nighttime}
        onClick={() => setIsDayTime(!isDayTime)}
        alt={isDayTime ? "Daytime" : "Night time"}
      />
    </div>
  );
}

export default App;

MULTIPLAYER

???

and dozens more...

😱😕😭😤🤬🤯

No Implementation details

third party dependency

No Implementation details

third party dependency

💰💰💰

No Implementation details

third party dependency

💰💰💰💰💰​💰💰💰💰💰​💰💰💰​

No Implementation details

Polling

Polling

GET​

Polling

GET​
GET​

Polling

GET​
GET​
GET​
const express = require("express");
const app = express();

let lightOn = false;

app.get("/polling", (req, res) => res.send(lightOn));
app.post("/polling", (req, res) => {
  lightOn = !lightOn;
  res.send(lightOn);
});
import React, { useState, useEffect } from "react";
import daytime from "./daytime.png";
import nighttime from "./nighttime.png";

import "./App.css";

const API_URL = "http://localhost:4000/polling";

function App() {
  const [isDayTime, setIsDayTime] = useState(true);
  const backgroundColor = isDayTime ? "#efefef" : "#212121";

  useEffect(() => {
    setInterval(async () => {
      const response = await (await fetch(API_URL)).text();
      setIsDayTime(response === "true");
    }, 500);
  }, []);

  return (
    <div className="App" style={{ backgroundColor }}>
      <img
        src={isDayTime ? daytime : nighttime}
        onClick={() => fetch(API_URL, { method: "POST" })}
        alt={isDayTime ? "Daytime" : "Night time"}
      />
    </div>
  );
}

export default App;

SERVER SENT EVENTS

Server Sent Events

GET​

Server Sent Events

GET​

Server Sent Events

GET​

Server Sent Events

GET​
const express = require("express");
const app = express();

const PubSub = require("pubsub-js");

app.get("/sse", (req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    Connection: "keep-alive"
  });

  res.write(`data:${lightOn}\n\n`);

  PubSub.subscribe("daytime_nighttime", function(event, data) {
    res.write(`data:${lightOn}\n\n`);
  });
});
app.post("/sse", (req, res) => {
  lightOn = !lightOn;
  PubSub.publish("daytime_nighttime", lightOn.toString());
  res.send(lightOn);
});
import React, { useState, useEffect } from "react";
import daytime from "./daytime.png";
import nighttime from "./nighttime.png";

import "./App.css";

const API_URL = "http://localhost:4000/sse";

function App() {
  const [isDayTime, setIsDayTime] = useState(true);
  const backgroundColor = isDayTime ? "#efefef" : "#212121";

  useEffect(() => {
    const eventSource = new EventSource(API_URL);
    eventSource.onmessage = event => setIsDayTime(event.data === "true");
    return () => eventSource.close();
  }, []);

  return (
    <div className="App" style={{ backgroundColor }}>
      <img
        src={isDayTime ? daytime : nighttime}
        onClick={() => fetch(API_URL, { method: "POST" })}
        alt={isDayTime ? "Daytime" : "Night time"}
      />
    </div>
  );
}

export default App;

Server Sent Events

100 birds

WEbsockets

Websockets

HANDSHAKE
const WebSocket = require("ws");
const ws_server = new WebSocket.Server({ port: 5000 });

const GRID_DIMENSION = 10;
const dayTimeArray = [...Array(GRID_DIMENSION)].map(x =>
  Array(GRID_DIMENSION).fill(false)
);

ws_server.on("connection", ws => {
  ws.on("message", message => {
    const { row, column, isDayTime } = JSON.parse(message);

    dayTimeArray[row][column] = isDayTime;

    ws_server.clients.forEach(client =>
      client.send(JSON.stringify(dayTimeArray))
    );
  });

  ws.send(JSON.stringify(dayTimeArray));
});
import React, { useState, useEffect } from "react";
import daytime from "./daytime.png";
import nighttime from "./nighttime.png";
import { w3cwebsocket as WebSocket } from "websocket";

import "./App.css";

const API_URL = "ws://localhost:5000";
const client = new WebSocket(API_URL);

function App() {
  const GRID_DIMENSION = 10;
  const [isDayTimeArray, setIsDayTimeArray] = useState(
    [...Array(GRID_DIMENSION)].map(x => Array(GRID_DIMENSION).fill(false))
  );

  useEffect(() => {
    client.onmessage = async event => setIsDayTimeArray(JSON.parse(event.data));
  }, []);

  return (
    ...
  );
}

export default App;
  return (
    <div className="App">
      {isDayTimeArray.map((row, rowIndex) => (
        <div>
          {row.map((isDayTime, columnIndex) => (
            <div
              className="column"
              style={{
                padding: 15,
                backgroundColor: isDayTime ? "#fff" : "#222"
              }}
            >
              <img
                src={isDayTime ? daytime : nighttime}
                onClick={() =>
                  client.send(
                    JSON.stringify({
                      row: rowIndex,
                      column: columnIndex,
                      isDayTime: !isDayTime
                    })
                  )
                }
                alt={isDayTime ? "Daytime" : "Night time"}
                style={{ width: 110, height: "auto" }}
              />
            </div>
          ))}
        </div>
      ))}
    </div>
  );

Websockets

GRAPHQL SUBSCRIPTIONS

WEBRTC

LESSONS

Minimize latency

Be careful with state

Know your use case

Questions?

Jayden Windle

twitter: @jayden_windle

github: @jaydenwindle

Made with Slides.com