Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
IDIEP-9
AuthorPavel Tupitsyn
SponsorPavel Tupitsyn
Created20-NOV-2017
Status
Status
colourGreyGreen
titleDRAFT

...

COMPLETED


Table of Contents

Info

This page includes low-level protocol documentation that might be outdated and is not maintained. Refer to the official protocol documentation here: https://apacheignite.readme.io/docs/binary-client-protocol

Motivation

Implement thin Ignite client in any programming language / platform using a well-defined binary connectiona protocol.

...

NameType CodeSize (bytes)
byte11
short22
int34
long48
float54
double68
char72
bool81
string94 bytes length + length * 2Utf8 byte count + Utf8 bytes
UUID (Guid)10816
date118 (milliseconds from 1 Jan 1970)
byte array124 bytes length + length
short array134 bytes length + length * 2
int array144 bytes length + length * 4
long array154 bytes length + length * 8
float array164 bytes length + length * 4
double array174 bytes length + length * 8
char array184 bytes length + length * 2
bool array194 bytes length + length
string array204 bytes length + variable length strings, see above. Nulls (byte 101) are allowed.
UUID (Guid) array214 bytes length + length * 816. Nulls (byte 101) are allowed.
date array224 bytes length + length * 8. Nulls (byte 101) are allowed.
object array234 bytes length + 4 bytes element type id + variable size binary objects
map254 bytes length + byte type (1 = HASH_MAP, 2 = LINKED_HASH_MAP) + length * (BinaryObject + BinaryObject)
NULL1010


Complex Objects

Complex objects consist of a 24-byte header and a , set of fields (key-value pairsbinary objects), and a schema (field ids and positions).

Header
byteObject type code, always 103
byteVersion, always 1
shortFlags, see below, USER_TYPE = 1, HAS_SCHEMA = 2
intType id, Java-style hash code of the type name
intHash code, Java-style hash of contents without header, necessary for comparisons
intLength, including header
intSchema Id, see below
intSchemaOffset, see below

 

Message format

All messages, request and response, including handshake, start with int message length (excluding these first 4 bytes). E.g. empty message would be represented by 4 zero bytes.

intLength of Payload
...Payload

Length is omitted in all message descriptions below for brevity.

Handshake

The first message upon connection establishment must be a handshake. Handshake ensures that client and server versions are compatible.

Request
byteHandshake code, always 1
shortVersion major
shortVersion minor
shortVersion patch
byte

Client code, always 2

Response (success)
byteSuccess flag, 1
Response (failure)
byteSuccess flag, 0
shortServer version major
shortServer version minor
shortServer version patch
stringError message

Client Operations

Schema offset from the header start, position where fields end
BinaryObject * nFields
(int + int) * nSchema, fieldId (Java-style hash of field name) + offset (from header start)

 

Wrapped Binary Objects

One ore more binary objects can be wrapped in an array. This allows reading, storing, passing and writing objects efficiently without understanding their contents, performing simple byte copy.

All cache operations return complex objects inside a wrapper (but not primitives).

byteType code, always 27
intByte array size
n bytesPayload
intOffset of the object within array (array can contain an object graph, this offset points to the root object)

Message format

All messages, request and response, including handshake, start with int message length (excluding these first 4 bytes). E.g. empty message would be represented by 4 zero bytes.

intLength of Payload
...Payload

Length is omitted in all message descriptions below for brevity.

Handshake

The first message upon connection establishment must be a handshake. Handshake ensures that client and server versions are compatible.

Request
byteHandshake code, always 1
shortVersion major
shortVersion minor
shortVersion patch
byte

Client code, always 2

Response (success)
byteSuccess flag, 1
Response (failure)
byteSuccess flag, 0
shortServer version major
shortServer version minor
shortServer version patch
stringError message

Client Operations

 Upon successful handshake client can  Upon successful handshake client can start performing operations by sending a request with specific op code. Each operation has it's own request and response format, with a common header.

...

Operation codes and request ids are omitted everywhere below for brevity.


OP_CACHE_GET = 11000

Retrieves a value from cache by key.

...

Response
BinaryObjectvalue

 

OP_CACHE_GET_ALL = 12

Cache flags

GET and all other cache operations include flags byte.

1KEEP_BINARY

Indicates wether IgniteCache.withKeepBinary should be called on the server side.

This flag has effect only for OP_QUERY_SCAN when Java filter is used.

Other operations ignore the flag and call withKeepBinary anyway.

 

 

OP_CACHE_GET_ALL = 1003

Retrieves Retrieves multiple values from cache given multiple keys. 

...

Response
intresult count
(BinaryObject + BinaryObject) * countResulting key-value pairs. Keys that are not present in the cache are not included.

 

OP_CACHE_PUT = 4 1001

Puts a value with a given key to cache (overwriting existing value if any).

...

Empy response.


OP_CACHE_PUT_ALL = 201004

Puts multiple key-value pairs to cache (overwriting existing associations if any).

...

Empy response.



OP_CACHE_CONTAINS_KEY = 101011

Returns a value indicating whether given key is present in cache.

...

 


OP_CACHE_CONTAINS_KEYS = 111012

Returns a value indicating whether all given keys are present in cache.

...

Response
boolTrue when keys are present, false otherwise

 


OP_CACHE_GET_AND_PUT = 131005

Puts a value with a given key to cache, returning previous value for that key.

...

OP_CACHE_GET_AND_REPLACE = 14 1006

Puts a value with a given key to cache, returning previous value for that key, if and only if there is a value currently mapped for that key.

...

OP_CACHE_GET_AND_REMOVE = 151007

Removes the cache entry with specified key, returning the value. 

...

 

OP_CACHE_PUT_IF_ABSENT = 16 1002

Puts a value with a given key to cache only if the key does not already exist. 

...

OP_CACHE_GET_AND_PUT_IF_ABSENT = 171008

Puts a value with a given key to cache only if the key does not already exist.  

...

Response
BinaryObjectPreviously contained value regardless of whether put happened or not.


 

 

OP_CACHE_REPLACE = 18 1009

Puts a value with a given key to cache only if the key already exists. 

...

OP_CACHE_REPLACE_IF_EQUALS = 19 1010

Puts a value with a given key to cache only if the key already exists and value equals provided value. 

...

Response
boolvalue indicating whether replace happened


 

OP_CACHE_CLEAR = 211013

Clears the cache without notifying listeners or cache writers.

...

Empy response.


 

OP_CACHE_CLEAR_KEY = 221014

 

Clears the cache key without notifying listeners or cache writers.

...

Empy response.

 

 

OP_CACHE_CLEAR_KEYS = 23 1015

 

Clears the cache keys without notifying listeners or cache writers. 

...

Empy response.

 

 

OP_CACHE_REMOVE_KEY = 241016

Removes an entry with a given key, notifying listeners and cache writers.

...

OP_CACHE_REMOVE_IF_EQUALS = 25 1017

Removes an entry with a given key if provided value is equal to actual value, notifying listeners and cache writers. 

...

Response
boolvalue indicating whether remove happened

 

 

OP_CACHE_GET_SIZE = 26 1020

Gets the cache size.  

Request
int
Cache ID: Java-style hash code of the cache name
byteflags
intPeek mode count. Can be 0, which means ALL.
byte * countPeek modes. ALL = 0, NEAR = 1, PRIMARY = 2, BACKUP = 3
Response
longCache size


 

 

OP_CACHE_REMOVE_KEYS = 271018

 

Removes entries with given keys, notifying listeners and cache writers. 

...

Empty response.

 

 


OP_CACHE_REMOVE_ALL = 28 1019

Removes all entries from cache, notifying listeners and cache writers. 

...

OP_CACHE_CREATE_WITH_NAME = 291051 

Creates a cache with a given name. Cache template can be applied if there is '*' in the cache name. Throws exception if a cache with specified name already exists. 

Request
string
Cache name

 


Empty response.

 


 

OP_CACHE_GET_OR_CREATE_WITH_NAME = 301052

 

Creates a cache with a given name. Cache template can be applied if there is '*' in the cache name. Does nothing if the cache exists.

...

Empty response.

 


 

OP_CACHE_DESTROY = 311056

Destroys cache with a given name.

Request
stringint
Cache nameID

Empty response.


 

OP_CACHE_GET_NAMES = 321050

Gets existing cache names.

...

OP_CACHE_GET_CONFIGURATION = 331055

Gets cache configuration

Request
intCache ID: Java-style hash code of the cache name

...

Cache configuration is sent and received by server in the following format:

CacheConfiguration
intLength of the configuration, in bytes
intCacheAtomicityMode, TRANSACTIONAL = 0, ATOMIC = 1
intBackups
intCacheMode, LOCAL = 0, REPLICATED = 1, PARTITIONED = 2
boolCopyOnRead
stringDataRegionName
boolEagerTtl
boolStatisticsEnabled
stringGroupNameboolinvalidate
longDefaultLockTimeout (milliseconds)
intMaxConcurrentAsyncOperations
intMaxQueryIterators
stringName
boolIsOnheapcacheEnabled
intPartitionLossPolicy, READ_ONLY_SAFE = 0, READ_ONLY_ALL = 1, READ_WRITE_SAFE = 2, READ_WRITE_ALL = 3, IGNORE = 4
intQueryDetailMetricsSize
intQueryParallelism
boolReadFromBackup
intRebalanceBatchSize
longRebalanceBatchesPrefetchCount
longRebalanceDelay (milliseconds)
intRebalanceMode, SYNC = 0, ASYNC = 1, NONE = 2
intRebalanceOrder
longRebalanceThrottle (milliseconds)
longRebalanceTimeout (milliseconds)
boolSqlEscapeAll
intSqlIndexInlineMaxSize
stringSqlSchema
intWriteSynchronizationMode, FULL_SYNC = 0, FULL_ASYNC = 1, PRIMARY_SYNC = 2
intCacheKeyConfiguration count
CacheKeyConfiguration * count
CacheKeyConfiguration
stringType name
stringAffinity key field name
intQueryEntity count
QueryEntity * count
QueryEntity
stringKey type name
stringValue type name
stringTable name
stringKey field name
stringValue field name
intQueryField count
QueryField * count
QueryField
stringName
stringType name
boolIs key field
boolIs NotNull constraint field
intAlias count
(string + string) * countField name aliases
intQueryIndex count
QueryIndex * count
QueryIndex
stringIndex name
byteIndex type, SORTED = 0, FULLTEXT = 1, GEOSPATIAL = 2
intInline size
intField count
(string + bool) * countFields (name + IsDescensing)

...

OP_CACHE_CREATE_WITH_CONFIGURATION = 34 1053

Creates cache with provided configuration. Throws an exception if the name is already in use. 

Request
CacheConfigurationCache config (see format above)

Empty response.

 

OP_CACHE_GET_OR_CREATE_WITH_CONFIGURATION = 35 

Creates cache with provided configuration. Does nothing if the name is already in use.  

Request
CacheConfigurationCache config (see format above)

 Empty response.

 

 

OP_QUERY_SQL = 36 

Performs SQL query. 

Request
intCache ID: Java-style hash code of the cache name
stringQuery entity type name
stringSQL
intArgument count
BinaryObject * countArguments
boolDistributed joins
boolLocal query
boolReplicated only
intCursor page size
longTimeout (milliseconds)

Response includes first page of results.

Response
longCursor id. Can be closed with OP_RESOURCE_CLOSE.
intRow count for the first page
(Object + Object) * countCache entries, key + value
bool

Indicates whether more results are available to be fetched with OP_QUERY_SQL_CURSOR_GET_PAGE.

When true, query cursor is closed automatically.

 

OP_QUERY_SQL_CURSOR_GET_PAGE = 37 

Retrieves next SQL query cursor page by cursor id from OP_QUERY_SQL. 

Request
longCursor id
Response
longCursor id
intRow count
(Object + Object) * countCache entries, key + value
bool

Indicates whether more results are available to be fetched with OP_QUERY_SQL_CURSOR_GET_PAGE.

When true, query cursor is closed automatically.

 

OP_RESOURCE_CLOSE = 9

Closes a resource, such as query cursor.

Request
longResource id

Empty response.

 

OP_QUERY_SQL_FIELDS = 38

Performs SQL fields query

Request
intCache ID: Java-style hash code of the cache name
stringDefault schema for the query, can be null
intQuery cursor page size
intMax rows
stringSQL
intArgument count
BinaryObject * countArguments
byteStatement type, ANY = 0, SELECT = 1, UPDATE = 2
boolDistributed joins
boolLocal
boolReplicated Only
boolEnforce Join Order
boolColocated
boolLazy
longTimeout (milliseconds)
boolInclude field names
Response
longCursor id. Can be closed with OP_RESOURCE_CLOSE.
intField (column) count

Optionally, when IncludeFieldNames is true in request

string * count

Column names
intFirst page row count
BinaryObject * columnCountColumn (field) values
boolIndicates whether more results are available to be retrieved with OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE

OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE = 39

Retrieves next query page.

Request
longCursor id
Response
intRow count
BinaryObject * columnCountColumn values
boolIndicates whether more results are available to be retrieved with OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE

OP_GET_BINARY_TYPE_NAME = 2

Gets the platform-specific full binary type name by id. For example, .NET and Java can map to the same type Foo, but classes will be Apache.Ignite.Foo in .NET and org.apache.ignite.Foo in Java.

Names are registered with OP_REGISTER_BINARY_TYPE_NAME.

Request
bytePlatform id, JAVA = 0, DOTNET = 1
intType id
Response
stringBinary type name

...

Gets the binary type information by id.

Request
intType id
Response
intType id
stringType name
stringAffinity key field name
intBinaryField count
BinaryField * count
BinaryField
stringField name
intType id
intField id
boolIs enum
int (if isEnum)Enum field count
(string + int) * count (if isEnum)Enum values
intSchema count
(int + int[]) * countBinary schemas, set of (schemaId + fieldIds) pairs

 

...

intLength of the configuration, in bytes
shortNumber of configuration properties
(short + ...) * nConfiguration property data

Any number of configuration properties can be provided. Name is required.

Cache configuration data is specified in key-value form, where key is `short` property id and value is property-specific data. Table below describes all available properties.

 

Property codeProperty typeDescription
2intCacheAtomicityMode, TRANSACTIONAL = 0, ATOMIC = 1
3intBackups
1intCacheMode, LOCAL = 0, REPLICATED = 1, PARTITIONED = 2
5boolCopyOnRead
100stringDataRegionName
405boolEagerTtl
406boolStatisticsEnabled
400stringGroupName
402longDefaultLockTimeout (milliseconds)
403intMaxConcurrentAsyncOperations
206intMaxQueryIterators
0stringName
101boolIsOnheapcacheEnabled
404intPartitionLossPolicy, READ_ONLY_SAFE = 0, READ_ONLY_ALL = 1, READ_WRITE_SAFE = 2, READ_WRITE_ALL = 3, IGNORE = 4
202intQueryDetailMetricsSize
201intQueryParallelism
6boolReadFromBackup
303intRebalanceBatchSize
304longRebalanceBatchesPrefetchCount
301longRebalanceDelay (milliseconds)
300intRebalanceMode, SYNC = 0, ASYNC = 1, NONE = 2
305intRebalanceOrder
306longRebalanceThrottle (milliseconds)
302longRebalanceTimeout (milliseconds)
205boolSqlEscapeAll
204intSqlIndexInlineMaxSize
203stringSqlSchema
4intWriteSynchronizationMode, FULL_SYNC = 0, FULL_ASYNC = 1, PRIMARY_SYNC = 2
401int + CacheKeyConfiguration * count

CacheKeyConfiguration count

CacheKeyConfiguration
stringType name
stringAffinity key field name
200int + QueryEntity * count
QueryEntity
stringKey type name
stringValue type name
stringTable name
stringKey field name
stringValue field name
intQueryField count
QueryField * count
QueryField
stringName
stringType name
boolIs key field
boolIs NotNull constraint field
intAlias count
(string + string) * countField name aliases
intQueryIndex count
QueryIndex * count
QueryIndex
stringIndex name
byteIndex type, SORTED = 0, FULLTEXT = 1, GEOSPATIAL = 2
intInline size
intField count
(string + bool) * countFields (name + IsDescensing)




Empty response.


 

OP_CACHE_GET_OR_CREATE_WITH_CONFIGURATION = 1054

Creates cache with provided configuration. Does nothing if the name is already in use. Same request format as above. Empty response.


 

OP_QUERY_SQL = 2002

Performs SQL query. 

Request
intCache ID: Java-style hash code of the cache name
stringQuery entity type name
stringSQL
intArgument count
BinaryObject * countArguments
boolDistributed joins
boolLocal query
boolReplicated only
intCursor page size
longTimeout (milliseconds)

Response includes first page of results.

Response
longCursor id. Can be closed with OP_RESOURCE_CLOSE.
intRow count for the first page
(Object + Object) * countCache entries, key + value
bool

Indicates whether more results are available to be fetched with OP_QUERY_SQL_CURSOR_GET_PAGE.

When true, query cursor is closed automatically.


 

OP_QUERY_SQL_CURSOR_GET_PAGE = 2003

Retrieves next SQL query cursor page by cursor id from OP_QUERY_SQL. 

Request
longCursor id
Response
longCursor id
intRow count
(Object + Object) * countCache entries, key + value
bool

Indicates whether more results are available to be fetched with OP_QUERY_SQL_CURSOR_GET_PAGE.

When true, query cursor is closed automatically.

 


OP_RESOURCE_CLOSE = 0

Closes a resource, such as query cursor.

Request
longResource id

Empty response.

 

OP_QUERY_SQL_FIELDS = 2004

Performs SQL fields query

Request
intCache ID: Java-style hash code of the cache name
stringDefault schema for the query, can be null
intQuery cursor page size
intMax rows
stringSQL
intArgument count
BinaryObject * countArguments
byteStatement type, ANY = 0, SELECT = 1, UPDATE = 2
boolDistributed joins
boolLocal
boolReplicated Only
boolEnforce Join Order
boolColocated
boolLazy
longTimeout (milliseconds)
boolInclude field names
Response
longCursor id. Can be closed with OP_RESOURCE_CLOSE.
intField (column) count

Optionally, when IncludeFieldNames is true in request

string * count

Column names
intFirst page row count
BinaryObject * columnCountColumn (field) values
boolIndicates whether more results are available to be retrieved with OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE



OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE = 2005

Retrieves next query page.

Registers the platform-specific full binary type name by id. For example, .NET and Java can map to the same type Foo, but classes will be Apache.Ignite.Foo in .NET and org.apache.ignite.Foo in Java.

Request
bytePlatform id, JAVA = 0, DOTNET = 1
intType id
stringType name

Empty response.

OP_PUT_BINARY_TYPE = 6

Registers binary type information in cluster.

Request
intType id
stringType name
stringAffinity key field name
intBinaryField count
BinaryField * count
BinaryField
stringField name
intType id
intField id
boolIs enum
int (if isEnum)Enum field count
(string + int) * count (if isEnum)Enum values
intSchema count
(int + int[]) * countBinary schemas, set of (schemaId + fieldIds) pairs

 Empty response.

 

...

Performs scan query.

Request
intCache ID: Java-style hash code of the cache name
BinaryObjectFilter object
byte (if filter object is not null)Filter platform, JAVA = 1, DOTNET = 2, CPP = 3
intCursor page size
intPartition to query (negative to query entire cache)
boolLocal flag
Response
longCursor id

 

OP_QUERY_SCAN_CURSOR_GET_PAGE = 8Retrieves next SQL query cursor page by cursor id from OP_QUERY_SCAN. 

Request
longCursor id
long
ResponseCursor id
intRow count
BinaryObject * columnCountColumn values(Object + Object) * countCache entries, key + value
boolIndicates whether more results are available to be fetched retrieved with OP_QUERY_SQL_SCANFIELDS_CURSOR_GET_PAGE.

When true, query cursor is closed automatically.

 

Message Exchange Example

As an example let's see how to connect to Ignite instance on a local machine and retrieve an int value for a given int key, in pseudocode.



OP_GET_BINARY_TYPE_NAME = 3000

Gets the platform-specific full binary type name by id. For example, .NET and Java can map to the same type Foo, but classes will be Apache.Ignite.Foo in .NET and org.apache.ignite.Foo in Java.

Names are registered with OP_REGISTER_BINARY_TYPE_NAME.

Request
bytePlatform id, JAVA = 0, DOTNET = 1
intType id
Response
stringBinary type name


OP_GET_BINARY_TYPE = 3002

Gets the binary type information by id.

Request
intType id
Response
bool

False: binary type does not exist, response end.

True: binary type exists, response as follows.

intType id
stringType name
stringAffinity key field name
intBinaryField count
BinaryField * count
BinaryField
stringField name
intType id
intField id
boolIs enum
int (if isEnum)Enum field count
(string + int) * count (if isEnum)Enum values
intSchema count
(int (schema id) + int (field count) + int (field id) * n) * countBinary schemas, set of (schemaId + fieldIds) pairs

 


OP_REGISTER_BINARY_TYPE_NAME = 3001

Registers the platform-specific full binary type name by id. For example, .NET and Java can map to the same type Foo, but classes will be Apache.Ignite.Foo in .NET and org.apache.ignite.Foo in Java.

Request
bytePlatform id, JAVA = 0, DOTNET = 1
intType id
stringType name

Empty response.



OP_PUT_BINARY_TYPE = 3003

Registers binary type information in cluster.

Request
intType id
stringType name
stringAffinity key field name
intBinaryField count
BinaryField * count
BinaryField
stringField name
intType id
intField id
boolIs enum
int (if isEnum)Enum field count
(string + int) * count (if isEnum)Enum values
intSchema count
(int (schema id) + int (field count) + int (field id) * n) * countBinary schemas, set of (schemaId + fieldIds) pairs

 Empty response.

 


OP_QUERY_SCAN = 2000

Performs scan query.

Request
intCache ID: Java-style hash code of the cache name
BinaryObjectFilter object
byte (if filter object is not null)Filter platform, JAVA = 1, DOTNET = 2, CPP = 3
intCursor page size
intPartition to query (negative to query entire cache)
boolLocal flag
Response
longCursor id
intRow count for the first page
(Object + Object) * countCache entries, key + value

bool

Indicates whether more results are available to be fetched with OP_QUERY_SCAN_CURSOR_GET_PAGE

 


OP_QUERY_SCAN_CURSOR_GET_PAGE = 2001

Retrieves next SQL query cursor page by cursor id from OP_QUERY_SCAN. 

Request
longCursor id
Response
longCursor id
intRow count
(Object + Object) * countCache entries, key + value
bool

Indicates whether more results are available to be fetched with OP_QUERY_SCAN_CURSOR_GET_PAGE.

When true, query cursor is closed automatically.

 



Message Exchange Example

As an example let's see how to connect to Ignite instance on a local machine and retrieve an int value for a given int key, in pseudocode.

Code Block
var socket = openSocket("127.0.0.1:10800");
 
// Message length
socket.writeInt(8);
 
// Handshake operation
socket.writeByte(1);
 
// Protocol version 1.0.0
socket.writeShort(1);
socket.writeShort(0);
socket.writeShort(0);
 
// Client type: thin client
socket.writeByte(2);
 
// Receive result
var resLen = socket.readInt();
assert resLen == 1;  // Success message length is 1
var res = socket.readByte();
assert res == 1;  // Success code
// END HANDSHAKE
 
 
// Perform OP_CACHE_GET
// Message length
socket.writeInt(20)
 
// Op code = OP_CACHE_GET
socket.writeShort(1000);
 
// Request id (can be anything; does not matter for simple blocking socket IO)
var reqId = 1;
socket.writeLong(reqId);
 
// Cache id
var cacheName = "myCache";
var cacheId = javaHashCode(cacheName);
socket.writeInt(cacheId);
 
// Flags = none
socket.writeByte(0);
 
// Cache key 
socket.writeByte(3);  // Integer type code
socket.writeInt(1);  // Our cache value
 
// Read result
var len = socket.readInt();
assert len == 17;   // requestId (8) + status code (4) + int object (1 + 4)
 
var resReqId = socket.readLong();
assert reqId == resReqId;
 
var statusCode = socket.readInt();
assert statusCode == 0;  // Success
 
var resTypeCode = socket.readByte();
assert restypeCode == 3;  // Integer
 
var res = socket.readInt();
print(res);  // Resulting cache value


Complex Binary Object Example

An example of writing a custom object with a single integer field, in pseudocode:

Code Block
// Header
socket.writeByte(103);  // Binary object type code
socket.writeByte(1);  // Binary object format version
socket.writeShort(1 + 2);  // Flags, user type + has schema
socket.writeInt(1512523596);  // Type id, Java-style hash code of "MyType"
socket.writeInt(0);  // Hash code, 0 for simplicity
socket.writeInt(24 + 5 + 8);  // Object length, header + int field (byte type + 4 bytes value) + schema (4 bytes id + 4 bytes offset)
socket.writeInt(0);  // Schema id, for simplicity
socket.writeInt(24 + 5);  // Schema offset, header size + one int field
 
// Fields
socket.writeByte(3);  // Field type, int
socket.writeInt(42);  // Field value
 
// Schema
socket.writeInt(1515208398);  // Field id, Java hash of "myfield"
socket.writeInt(24);  // Field position from object start, right after 24-byte header

Reading binary object and retrieving field value:

Code Block
// Header
assert socket.readByte() == 103;
assert socket.readByte() == 1;
assert socket.readByte() == 1 + 2;
var typeId = socket.ReadInt();
var hash = socket.readInt();
var len = socket.ReadInt();
var schemaId = socket.ReadInt();
var schemaOffset = socket.ReadInt();
 
// Read field data into array, everything between header and schema
var fieldData = socket.readByteArray(schemaOffset - 24);
 
// Read schema
var fieldCount = (len - schemaOffset) / 8;
var fieldIds = new int[fieldCount];
var fieldOffsets = new int[fieldCount];
 
for (int i = 0; i < fieldCount; i++)
{
  fieldIds[i] = socket.readInt();
  fieldOffsets[i] = socket.readInt();
}
 
// Let's suppose that user wants a value of the field named "myfield"
var fieldName = "myfield";
var fieldId = getJavaHash(fieldName);  // 1515208398
var fieldIdx = fieldIds.indexOf(fieldId);  // Can be missing, handle accordingly
var fieldOffset = fieldOffsets[fieldsIdx];
 
// We got the field offset, now read binary object from fieldData
var reader = new ArrayReader(fieldData);
reader.seek(fieldOffset - 24);
 
var fieldType = reader.readByte();
if (fieldType = 3)  // int
{
  var fieldVal = reader.readInt();
}
else if (fieldVal = 103)
{
  // Nested binary object
  ...
}
else ... 
Code Block
var socket = openSocket("127.0.0.1:10800");
 
// Message length
socket.writeInt(8);
 
// Handshake operation
socket.writeByte(1);
 
// Protocol version 1.0.0
socket.writeShort(1);
socket.writeShort(0);
socket.writeShort(0);
 
// Client type: thin client
socket.writeByte(2);
 
// Receive result
var resLen = socket.readInt();
assert resLen == 1;  // Success message length is 1
var res = socket.readByte();
assert res == 1;  // Success code
// END HANDSHAKE
 
 
// Perform OP_CACHE_GET
// Message length
socket.writeInt(20)
 
// Op code = OP_CACHE_GET
socket.writeShort(1);
 
// Request id (can be anything; does not matter for simple blocking socket IO)
var reqId = 1;
socket.writeLong(reqId);
 
// Cache id
var cacheName = "myCache";
var cacheId = javaHashCode(cacheName);
socket.writeInt(cacheId);
 
// Flags = none
socket.writeByte(0);
 
// Cache key 
socket.writeByte(3);  // Integer type code
socket.writeInt(1);  // Our cache value
 
// Read result
var len = socket.readInt();
assert len == 17;   // requestId (8) + status code (4) + int object (1 + 4)
 
var resReqId = socket.readLong();
assert reqId == resReqId;
 
var statusCode = socket.readInt();
assert statusCode == 0;  // Success
 
var resTypeCode = socket.readByte();
assert restypeCode == 3;  // Integer
 
var res = socket.readInt();
print(res);  // Resulting cache value

Discussion Links

http://apache-ignite-developers.2346864.n4.nabble.com/Thin-client-protocol-message-format-td20300.html

...

Tickets

See "thin client" component in JIRA

...