Giter Club home page Giter Club logo

velocystream's Introduction

Client / Server Communication (VST 1.1)

Version 1.1.0 of 23 November 2016

HTTP

Use VelocyPack as body. Content-Type is "application/vpack"

Binary Protocol

This is not a request / response protocol. It is symmetric (in principle). Messages can be sent back and forth, pipelined, multiplexed, uni-directional or bi-directional.

It is possible that a message generates

  • no response

  • exactly one response

  • multiple responses

The VelocyStream does not impose or specify or require one of the above behaviors. The application must define a behavior in general or on a per-request basis, see below. The server and client must then implement that behavior.

Message vs. Chunk

The consumer (client or server) will deal with messages. A message consists of one or more VelocyPacks (or in some cases of certain parts of binary data). How many VelocyPacks are part of a message is completely application dependent, see below for ArangoDB.

It is possible that the messages are very large. As messages can be multiplexed over one connection, large messages need to be split into chunks. The sender/receiver class will accept a vector of VelocyPacks, split them into chunks, send these chunks over the wire, assemble these chunks, generates a vector of VelocyPacks and passes this to the consumer.

Chunks

In order to allow reassemble chunks, each package is prefixed by a small header. A chunk is always at least 24 bytes long. The byte order is ALWAYS little endian. The format of a chunk is the following, regardless on whether it is the first in a message or a subsequent one:

name type description
length uint32_t total length in bytes of the current chunk, including this header
chunkX uint32_t chunk/isFirstChunk (upper 31bits/lowest bit), details see below
messageId uint64_t a unique identifier, it is the responsibility of the sender to generate such an identifier (zero is reserved for not set ID)
messageLength uint64_t the total size of the message.
Binary data binary data blob size b1

Clarification: "chunk" and "isFirstChunk" are combined into an unsigned 32bit value. Therefore it will be encoded as

uint32_t chunkX

and extracted as

chunk = chunkX >> 1

isFirstChunk = chunkX & 0x1

For the first chunk of a message, the low bit of the second uint32_t is set, for all subsequent ones it is reset. In the first chunk of a message, the number "chunk" is the total number of chunks in the message, in all subsequent chunks, the number "chunk" is the current number of this chunk.

The total size of the data package is (24 + b1) bytes. This number is stored in the length field. If one needs to send messages larger than UINT32_MAX, then these messages must be chunked. In general it is a good idea to restrict the maximal size to a few megabytes.

Notes:

When sending a (small) message, it is important (for performance reasons) to ensure that only one TCP packet is sent. For example, by using sendmmsg under Linux (https://blog.cloudflare.com/how-to-receive-a-million-packets/)

Implementors should nevertheless be aware that in TCP/IP one cannot enforce this and so implementations must always be aware that some part of the network stack can split packets and the payload might arrive in multiple parts!

ArangoDB

Request / Response

For an ArangoDB client, the request is of the following format, the array is a VelocyPack array:

[
/* 0 - version: */     1,                    // [int]
/* 1 - type: */        1,                    // [int] 1=Req, 2=Res,..
/* 2 - database: */    "test",               // [string]
/* 3 - requestType: */ 1,                    // [int] 0=Delete, ...
/* 4 - request: */     "/_api/collection",   // [string\]
/* 5 - parameter: */   { force: true },      // [[string]->[string]]
/* 6 - meta: */        { x-arangodb: true }  // [[string]->[string]]
]

Body (binary data)

If database is missing (entry is null), then "_system" is assumed.

type:

1 = Request
2 = Response (final response for this message id)
3 = Response (but at least one more response will follow)
1000 = Authentication

requestType:

0 = DELETE
1 = GET
2 = POST
3 = PUT
4 = HEAD (not used in VPP)
5 = PATCH
6 = OPTIONS (not used in VPP)

For example:

The HTTP request

http://localhost:8529/_db/test/_admin/echo?a=1&b=2&c[]=1&c[]=3

With header:

X-ArangoDB-Async: true

is equivalent to

[
  1,               // version
  1,               // type
  "test",          // database
  1,               // requestType GET
  "/_admin/echo",  // request path
  {                // parameters
    a: 1,
    b: 2,
    c: [ 1, 3 ]
  },
  {                // meta
    x-arangodb-async: true
  }
]

The request is a message beginning with one VelocyPack. This VelocyPack always contains the header fields, parameters and request path. If the meta field does not contain a content type, then the default "application/vpack" is assumed and the body will be one or multiple VelocyPack object.

The response will be

[
  1,                // 0 - version
  2 or 3,           // 1 - type
  400,              // 2 - responseCode
  { etag: "1234" }  // 3 - meta: [[str]->[str]]
]

Body (binary data)

Request can be pipelined or mixed. The responses are mapped using the "messageId" in the header. It is the responsibility of the sender to generate suitable "messageId" values.

The default content-type is "application/vpack".

Authentication

A connection can be authenticated with the following message:

[
  1,              // version
  1000,           // type
  "plain",        // encryption
  "admin",        // user
  "plaintext",    // password
]

or

[
  1,              // version
  1000,           // type
  "jwt",          // encryption
  "abcd..."       // token
]

The response is

{ "error": false }

if successful or

{ 
  "error": true,
  "errorMessage": "MESSAGE",
  "errorCode": CODE
}

if not successful, and in this case the connection is closed by the server. One can acquire a JWT token in the same way as with HTTP using the open, unauthenticated route /_open/auth with the same semantics as in the HTTP version. In this way, the complete authentication can be done in a single session via JWT.

Content-Type and Accept

In general the content-type will be VPP, that is the body is an object stored as VelocyPack.

Sometimes it is necessary to respond with unstructured data, like text, css or html. The body will be a VelocyPack object containing just a binary attribute and the content-type will be set accordingly.

The rules are as follows.

Http

Request: Content-Type

  • "application/json": the body contains the JSON string representation

  • "application/vpack": the body contains a velocy pack

There are some handler that allow lists of JSON (seperared by newline). In this case we also allow multiple velocy packs without any separator.

Request: Accept

  • "application/json": send a JSON string representation in the body, if possible

  • "application/vpack": send velocy pack in the body, if possible

If the request asked for "application/json" or "application/vpack" and the handler produces something else (i.e. "application/html"), then the accept is ignored.

If the request asked "application/json" and the handler produces "application/vpack", then the VPACK is converted into JSON.

If the request asked "application/vpack" and the handler produces "application/json", then the JSON is converted into VPACK.

VPP

Similar to HTTP with the exception: the "Accept" header is not supported and "application/json" will always be converted into "application/vpack". This means that the body contains one or more velocy-packs. In general it will contain one - notable exception being the import.

If the handler produces something else (i.e. "application/html"), then The body will be a binary blob (instead of a velocy-pack) and the content-type will be set accordingly.

The first bytes sent after a connection (the "client" side - even if the program is bi-directional, there is a server listening to a port and a client connecting to a port) are

VST/1.1\r\n\r\n

(11 Bytes)

velocystream's People

Contributors

neunhoef avatar

Stargazers

 avatar Michael Black Ritter avatar Aditya Mukhopadhyay avatar enginekit avatar savi2w avatar AICells avatar tristan avatar John Joyce avatar  avatar Alex avatar  avatar Jan avatar Benjamin E. Oliver avatar Witold Graca avatar Jan Zajic avatar

Watchers

Al Sargent avatar Marcin Swiderski avatar Matthew Von-Maszewski avatar Claudius Weinberger avatar Frank Celler avatar James Cloos avatar Simon avatar  avatar Sreenatha Reddy K R avatar Stanislav Filippov avatar David Costa Faidella avatar Ignacio Rodríguez avatar Heiko avatar Michele Rastelli avatar Kaveh Vahedipour avatar Jan avatar Manuel B. avatar  avatar Arthur Keen avatar Michael Hackstein avatar Alex Geenen avatar Palash Karia avatar Andrey Abramov avatar Markus Pfeiffer avatar  avatar Vadim Kondratev avatar Nikita Vaniasin avatar Luca Olivari avatar Ewout Prangsma avatar Wilfried Goesgens avatar Vitaly Pryakhin avatar Oliver Linares y Schwarzenberg avatar Michael Guerra avatar Lakhan Samani avatar Tariq Daouda avatar Terence Joubert avatar Stephen Holt avatar Julia Volmer avatar Nikhil Varma avatar Manuel Pöter avatar  avatar  avatar Adam Janikowski avatar kenneth Makobe avatar Jan avatar Jose (Jay) Martinez avatar  avatar

Forkers

krsreenatha

velocystream's Issues

Look forward to answering a few questions

I am implementing the client side of this protocol, but I have some questions. One reply of a messageId request may have multiple chunks and then one request may have multiple replies. How can I assemble the chunks and the replies and return them to the requester?

about velocy pack object sort

the velocy pack document show
"Objects are always stored with sorted key/value pairs, sorted by bytewise comparions of the keys on each nesting level. Sorting has some overhead but will allow looking up keys in logarithmic time later. Note that only the index table needs to be sorted, it is not required that the offsets in these tables are increasing. Since the index table resides after the actual subvalues, one can build up a complex VPack value by writing linearly."
I have a question whether the object that Velocystream transmits such as the parameter, meta, body must to be sort key and then code?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.