Rafał Lorenz edited this page Feb 23, 2018 · 16 revisions

Overview

The main idea of peer-cdn is to use WebRTC and Service Worker to allow assets such as scripts, images, videos, styles and other files to be shared between peers reducing server usage.

By importing peer-cdn into your service worker you get the access to exported PeerCDN class, Plugins and Strategies.

peer-cdn allow you to register listeners and add middleware to fetch event. For more information, see Middleware.

Bundle size

┌────────────────────────────────────────────────────┐
│                                                    │
│   Destination: lib/index.js                        │
│   Bundle size: 247.07 KB, Gzipped size: 72.45 KB   │
│                                                    │
└────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────┐
│                                                    │
│   Destination: es/index.js                         │
│   Bundle size: 256.63 KB, Gzipped size: 73.71 KB   │
│                                                    │
└────────────────────────────────────────────────────┘

Setting everything up

For full example please check this directory

Service worker

(function () {
  "use strict";

  // import peer-cdn into service worker
  // this path is exposed with server
  self.importScripts("/peer-cdn/index.js");

  const cachePlugin = new CachePlugin({ version: 1 });
  // since sw does not support webrtc yet we use PeerPlugin on client side 
  // and we delegate request to it with DelegatePlugin
  const delegatePlugin = new DelegatePlugin({ timeoutAfter: 5000 });
  const networkPlugin = new NetworkPlugin();

  function run() {
    const cdn = new PeerCDN();
    cdn.GET("/css/main.css", STRATEGIES.ordered,
      cachePlugin.getMiddleware,
      delegatePlugin.getMiddleware,
      networkPlugin.getMiddleware
    );

    // We need to register service worker events
    // cdn.register() will add listeners for install, activate and fetch
    // gaining required control
    cdn.register();
  }

  run();
})();

Main script

"use strict";

if ("serviceWorker" in navigator) {
  // since sw does not support webrtc yet
  // this is workaround to use it
  // we use PeerPlugin on client side
  const peerPlugin = new PeerPlugin({
    cacheName: CachePlugin.peerfetch + 1,
    timeoutAfter: 3000,
    servers: {
      iceServers: [
        {
          url: "stun:74.125.142.127:19302"
        }
      ]
    },
    constraints: {
      ordered: true
    },
  });

  // Set up a listener for messages posted from the service worker.
  // The service worker is set to post a message to specific client only
  // so you should see this message event fire once.
  // You can force it to fire again by visiting this page in an Incognito window.
  navigator.serviceWorker.addEventListener('message', function (event) {
    const request = new Request(event.data.url);
    // mock sw event wrapping request with object
    const middleware = peerPlugin.getMiddleware({ request });

    // run get method of a created middleware
    middleware.get()
      .then(function (response) {
        // return response to a service worker
        event.ports[0].postMessage(response);
      })
      .catch(function (error) {
        // return response to a service worker
        event.ports[0].postMessage(null);
      });
  });

  // register our service worker
  navigator.serviceWorker.register("sw.js")
    .then(function (registration) {
      // Registration was successful
      console.log("ServiceWorker registration successful with scope: ", registration.scope);
    })
    .catch(function (error) {
      console.error("Service Worker Error", error);
    });
}
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.