Question

I hope this is the right forum for this question, but I'm just looking to understand how Google Docs and Sheets works. How can multiple users edit the same sheet and see live changes without having to refresh their screen? I'm an old school web developer who's been out of the game for a while and was curious how something like that worked. How are they not each looking at their own instance of the webpage? It's not just a webpage, I presume, but then what is it? Sorry for the general question, but I would love if someone could point me to some reading that would explain this to me. I tried googling, but can't seem to find the right key words to use. Any search with "collaborate" or "live editing" just gives me instructions on HOW to use google docs rather than the explanation of how the code works to do that. Like I said, I've been out of the game for a while, and would appreciate even the correct key words to use to search for answers.

Was it helpful?

Solution

So fundamentally it is fairly complicated to do efficiently, especially with the need to support features like "undo", but we can walk through the problem step by step.

Lets say we wanted to make a distributed text editor, but to make things simpler it is append only. This means there is no backspace and no moving of the cursor to a different part of the document, just typing in characters.

Every connected user can type a character and the characters that are typed will be received by the server potentially out of order. In terms of how you can implement this part for the web: you can use standard HTTP requests to a given path in a REST-like way, you can use bidirectional communication with Websockets, or some technology built on top of those two.

Then, assuming there is only a single machine that acts as a server, you will need some data structure either in memory or on disk or both that serves as an authoritative reference for what the state of the document is. You can then give this to all users on any change, or periodically, or on some other interval using either Server Side push or Websockets.

You can probably imagine that the simplest way would be some buffer of characters on the server written to in the order requests arrive and sent out to connected clients as needed.

If you have more than one server or support more operations than just an append, things start to get a whole lot more difficult and you need to look into ways to distribute requests to the right place like Pub/Sub, Actor systems, or Queues and ways to efficiently and correctly handle sequences of edits like Logs, Structural Sharing, CRDTs (Conflict Free Replicated Datatypes), and more. A good, public, example of code that handles live editing is VSCode Live Share. I haven't personally done a deep dive, but that seems like a good reference if you feel like perusing or skimming the code.

But, that doesn't seem to be where your confusion starts. You asked "How are they not each looking at their own instance of the webpage". That is a far simpler question to answer.

As you know, websites are built out of HTML and CSS. They describe what to render on the page and how to render it. In the time I am assuming you started web development, this was basically all there was to it. In those days web browsers supported JavaScript, but it was used mostly to implement some minor functionality.

The big difference is that nowadays the capabilities of JavaScript have expanded significantly. You can make HTTP requests or set up those previously mentioned Websocket connections from JavaScript and there are a whole host of tools for both generating and updating the HTML displayed on the page depending on what data is loaded in.

They are both looking at their own instance of the web page, but those instances are kept in sync via real time communication with the server using the aforementioned web sockets or via periodic communication with the server using normal HTTP requests.

Generally data will be carried in the body of the HTTP response in some format like XML or JSON or something else. JavaScript code can then update its model, in memory, of what data should be displayed on the page and make the necessary edits to the HTML.

Now, there is a host of problems on the server side that need to be resolved to do this - the model is no longer just a pure "request/response" cycle and different servers might need to communicate - but the interface to that from the web browser is fairly simple.

If you need a more concrete example, try putting this into an index.html file and opening it on your computer. I took this from websocket.org

  <!DOCTYPE html>
  <meta charset="utf-8" />
  <title>WebSocket Test</title>
  <script language="javascript" type="text/javascript">

  var wsUri = "wss://echo.websocket.org/";
  var output;

  function init()
  {
    output = document.getElementById("output");
    testWebSocket();
  }

  function testWebSocket()
  {
    websocket = new WebSocket(wsUri);
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
  }

  function onOpen(evt)
  {
    writeToScreen("CONNECTED");
    doSend("WebSocket rocks");
  }

  function onClose(evt)
  {
    writeToScreen("DISCONNECTED");
  }

  function onMessage(evt)
  {
    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    websocket.close();
  }

  function onError(evt)
  {
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
  }

  function doSend(message)
  {
    writeToScreen("SENT: " + message);
    websocket.send(message);
  }

  function writeToScreen(message)
  {
    var pre = document.createElement("p");
    pre.style.wordWrap = "break-word";
    pre.innerHTML = message;
    output.appendChild(pre);
  }

  window.addEventListener("load", init, false);

  </script>

  <h2>WebSocket Test</h2>

  <div id="output"></div>

Does that make sense? Let me know if I missed the mark any.

Licensed under: CC-BY-SA with attribution
scroll top