Skip to main content

Syncing remote preso data

Related links:

One of the biggest features of LivePreso is remote preso mode. Using our websockets-based system for master-client syncing, this functionality gives us pixel perfect content with low bandwidth usage, client interaction development possibilities and tracking! The ultimate in client engagement.

In this section we will get you started, with some handy wrapper classes included in the latest Starting Point deck, as well as several common use-cases for working with vanilla LivePreso events.

As remote preso content bugs are largely invisible to our users (eg. they won't know if something's broken unless their client tells them) we highly recommend talking to your LivePreso content development trainer before beginning development, and booking in a code review and test early on to catch any pesky gotchas.

Taking a state-based approach

The new Starting Point deck includes custom functionality that allows for a more state-based approach when developing remote preso functionality. Download the latest Starting Point deck and check out the included slide docs on Bridge State to find out more.

Using vanilla LivePreso events

Triggering basic events

In order to send data between the master and client(s) of a remote preso we'll be using websockets, made available by Bridge.Event. Each event consists of an .on() and a .trigger() event pair, allowing us to pass serializable data between master and client.

Basic example:

$("#slideID").on("slideready", () => {
const $pageContainer = $("#slideID");
const $counter = $(".js-counter");
let counter = 0;

// Update DOM with starting value
$counter.text(counter);

// Register event listener
// This will be used by both the master and client
// to update the counter display in the DOM
Bridge.Event.on("master:updateCounter", (value) => {
$counter.text(value);
});

function onCounterClick() {
// Update counter value in the master's local variable
counter++;
// Trigger Bridge event for DOM update
Bridge.Event.trigger("master:updateCounter", counter);
}

// Register button click listener for all modes except client
if (!$("body").hasClass("client")) {
$(".js-btn-increase-counter", $pageContainer).on("click", onCounterClick);
}
});
warning

Events are scoped to the slide that creates them.

Client syncing

As the client slide maintains its own copy of the context (set at the time the presentation is started) and can load in at a delayed time, a race-condition exists where the client may miss the master's initial event triggers and become out of sync. To combat this, we have developed a simple pattern for requesting the latest data when the client arrives.

This is useful in situations where the context is being editing during a presentation (ie. not edited in prep and locked in place in time for the presentation), as well as for any other local variables that may not be persistent, but should be synced while the current slide is active.

How it works

  1. When the client arrives, it requests the latest context (or local) data from the master
  2. The master collects its data, and sends it to the client
  3. The client recieves the latest data and updates accordingly

When wanting to trigger a Bridge Event from the client it must use the client: prefix.

// eg. ``client`` triggers the "client:fetchPrice" event when it loads in
if ($("body").hasClass("client")) {
Bridge.Event.trigger("client:fetchPrice");
}

// The ``master`` receives this message and sets off a series of events:
// First it fetches the latest values from its context
if ($("body").hasClass("master")) {
Bridge.Event.on("client:fetchPrice", function () {
var latestPrices = Bridge.Context.match(".price", 0);

// Then it triggers its own event, sending the latest values
Bridge.Event.trigger("master:updateData", latestPrice);
});
}

// This event is then received by both the ``master`` and ``client``
// making sure they remain up to date and in sync, and reducing duplicate code
Bridge.Event.on("master:updateData", function (price) {
$(".price", "#slide_id").html("$" + price);
});
info

Events with the client: prefix will only be triggered from the client's browser.