Skip to content

How it works

Peter Kwan edited this page Jul 30, 2019 · 6 revisions

Outline

Each Muttlee client establishes a connection to the server. Messages are sent between client and server in a Data packet. The Data packet contains service and page information as well as column and row so that it can identify a character location on a specific page.

When a client connects, it is assigned a client ID. A client can request an initial page but by default it will be set to page 100. The page is then parsed from MRG format tti files and split into Data packets for description, timer, rows and fastext.

The server then listens for keystroke events. As a keystroke comes in it is logged and also retransmitted to all connected clients. In this way, all clients watching the same page get updated in real time. Every minute the keyevents are written back to their relevant tti page file and the keyevents log cleared. Also, when a key is typed, the client will show it on an orange background. When the key has been processed and come back from the server, the background is returned to normal to indicate that the server has captured the edit.

If another client opens the page then it is sent as normal but the whole keyevents log is played out to bring the client up to date.

Messages to the client are handled in sketch.js and are registered in socket.on handlers:

keystroke, blank, row, fastext, setpage, description, subpage, timer, id.

Message to the server are

keystroke, load, initialLoad, create, clearPage, disconnect

Server

The server part of Muttlee is Javascript running in Node. The main code is teletextserver.js with supporting javascript for pages and services.

teletextserver.js uses socket.io for networking, express for web services, stream and readline for file handling.

The initialisations set up all of the objects that we need. We create an express server and assign it port 8080. We then create a network socket to wrap around our server. Finally we set up an event handler that calls newConnection when a connection event happens.

newConnection() happens when the page is loaded. It reads URL parameters Service and Page if provided. The socket id is a unique number for the connection. It is sent to the client so that it can identify itself in future messages. We register event handlers for keystrokes and page loads.

doInitialLoad saves the initial page number and then calls doLoad.

doLoad loads a page and caches it if possible. It contains its own event handlers for reading files.

The data object is used for messages between the server and clients. A data object looks like this:

  var data = {
    S: "BBCNEWS/BBC",
    page: 100, // Page mpp
    s: 0, // subpage 0
    x: 0, // This signals that we should load the initial page (usually 100)
    y: 0,
    rowText:
  }

It is mainly used to signal keystrokes but it can also do rows and request pages. S is the service path. page is a hex page number 100..8FF. s is a subpage probably integer up to 100. x and y are the column, row address. rowText is the text to put at that location.

The service path needs to change as exposing file paths to the web interface is asking for trouble. In future the service should be a name and any path altering information should be trapped. The service name should also default to the main service so an invalid service will redirect to a valid page.

For single keystrokes there is key message called keyMessage. Originating from the client it sends a single character. keyMessage very simply rebroadcasts the key to all clients. It is the client that compares the service and page and if they match then it accepts the keyMessage. So any other client viewing the same page gets updated. So a service can be blank or a name like D2K.

What doesn't happen right now is that keyMessage should be applied to the server's copy of the page then we will have a powerful publishing platform.

package.json is the manifest used by node. app.yaml is also required by node. config.json is only for running on Google App Engine.

Clone this wiki locally