Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
145 lines (114 sloc) 4.64 KB

The Jinaga wire protocol is designed for resilience and performance. Built on top of WebSockets, the protocol is represented as the exchange of JSON documents. Each side sends a document when they have something to say; there is no request/response cadence.

Fact

A fact message sends a fact from one peer to the other. Facts have ids, which are unique only within the scope of the current session. They also carry a token, which is assumed (but not required) to be the hash of the fact. The token is used with the received fact, and is only generated by a client.

{
	type: "fact",
    id: 1,
    fact: {
        type: "Jinaga.User",
        publicKey: "----BEGIN PUBLIC KEY---XXXXX"
    },
    token: -1902729049
}

These IDs can be used as references in later fact messages. A fact reference also includes the hash of the fact, making lookup on the opposite side faster.

{
	type: "fact",
    id: 3,
    fact: {
        type: "List",
        name: "Chores",
        from: {
            id: 1,
            hash: -1902729049
        }
    },
    token: 430392748
}

During a given session, the use of references reduces redundancy, and improves the performance of the overall communication.

{
	type: "fact",
    id: 5,
    fact: {
        type: "Task",
        list: {
            id: 3,
            hash: 430392748
        },
        description: "Take out the trash"
    },
    token: -2014427633
}

{
    type: "fact",
    id: 7,
    fact: {
        type: "Task",
        list: {
            id: 3,
            hash: 430392748
        },
        description: "Deposit all the cash"
    },
    token: -2014427655
}

Between a given communicating pair of nodes, the ID is determined by the node that generates the fact. The ID has no meaning outside of the communication channel. The same fact may have different IDs between different pairs, or even between the same pair during different sessions.

The ID space within the channel is bifurcated so that the two nodes cannot generate the same ID. Clients generate odd numbered IDs, while servers generate even numbers. If the two nodes are peers, the client is the one that initiated the communication. If a race condition occurs in which both nodes in the pair generate the same fact, then either ID may be used by either party for the remainder of the session to refer to the same fact.

Received

When a server receives a fact message, it responds with a received message. This echoes back the token.

{
    type: "received",
    token: -1902729049
}

The client uses this message to remove the fact from its retry queue. If the connection is broken and then reestablished, this message does not need to be re-sent.

Logged In

The server sends a loggedIn message when the user has been authenticated. This occurs when the connection is established and a bearer token is included in the Authorized header. The token is validated, and the fact containing the user's public key is returned. The user's current profile -- according to the authentication provider -- is also returned.

{
    type: "loggedIn",
    userFact: {
        type: "Jinaga.User",
        publicKey: "----BEGIN PUBLIC KEY---XXXXX"
    },
    profile: {
        displayName: "Cliff Stoll"
    }
}

Watch

The client sends a watch message to begin watching for facts satisfying a specified query.

{
    type: "watch",
    start: {
        type: "List",
        name: "Chores",
        from: {
            type: "Jinaga.User",
            publicKey: "----BEGIN PUBLIC KEY---XXXXX"
        }
    },
    query: 'S.list F.type="Task"'
}

The query is expressed as a descriptive string. Each segment is a

  • P Predecessor
  • S Successor
  • F Field
  • E Exists condition (nested query in parentheses)
  • N Not exists condition (nested query in parentheses)

The server sends facts matching the query immediately. It continues to send facts as they arrive.

Stop

The client sends a stop message to tell the server to stop sending facts matching the specified query. The message contains the same fields as the watch message.

Query

The client sends a query message to request facts satisfying a specified query. The server responds with the facts that it currently knows about, and then terminates with a done message. It does not continue sending facts as it receives them.

The query message is similar to a watch, with the addition of a token. The token may be any value that the client chooses.

Done

The server responds to a query message with some number of facts followed by done. The done message carries the token specified in the query.