apache-ignite
286 строк · 8.4 Кб
1// Licensed to the Apache Software Foundation (ASF) under one or more
2// contributor license agreements. See the NOTICE file distributed with
3// this work for additional information regarding copyright ownership.
4// The ASF licenses this file to You under the Apache License, Version 2.0
5// (the "License"); you may not use this file except in compliance with
6// the License. You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15= Binary Client Protocol
16
17== Overview
18
19Ignite binary client protocol enables user applications to communicate with an existing Ignite cluster without starting a full-fledged Ignite node. An application can connect to the cluster through a raw TCP socket. Once the connection is established, the application can communicate with the Ignite cluster and perform cache operations using the established format.
20
21To communicate with the Ignite cluster, a client must obey the data format and communication details explained below.
22
23== Data Format
24
25=== Byte Ordering
26
27Ignite binary client protocol has little-endian byte ordering.
28
29=== Data Objects
30
31User data, such as cache keys and values, are represented in the Ignite link:key-value-api/binary-objects[Binary Object] format. A data object can be a standard (predefined) type or a complex object. For the complete list of data types supported, see the link:binary-client-protocol/data-format[Data Format] section.
32
33== Message Format
34
35All messages- requests and responses, including handshake, start with an `int` type message length (excluding these first 4 bytes) followed by the payload (message body).
36
37=== Handshake
38
39The binary client protocol requires a connection handshake to ensure that client and server versions are compatible. The following tables show the structure of handshake message request and response. Refer to the <<Example>> section on how to send and receive a handshake request and response respectively.
40
41
42[cols="1,2",opts="header"]
43|===
44|Request Type| Description
45|int| Length of handshake payload
46|byte| Handshake code, always 1.
47|short| Version major.
48|short| Version minor.
49|short| Version patch.
50|byte| Client code, always 2.
51|String| Username
52|String| Password
53|===
54
55
56[cols="1,2",opts="header"]
57|===
58| Response Type (success) | Description
59|int| Success message length, 1.
60|byte| Success flag, 1.
61|===
62
63
64[cols="1,2",opts="header"]
65|===
66|Response Type (failure) | Description
67|int| Error message length.
68|byte| Success flag, 0.
69|short| Server version major.
70|short| Server version minor.
71|short| Server version patch.
72|String| Error message.
73|===
74
75
76=== Standard Message Header
77
78Client operation messages are composed of a header and operation-specific data. Each operation has its own <<Client Operations,data request and response format>>, with a common header.
79
80The following tables and examples show the request and response structure of a client operation message header:
81
82
83[cols="1,2",opts="header"]
84|===
85|Request Type | Description
86|int| Length of payload.
87|short| Operation code
88|long| Request id, generated by client and returned as-is in response
89|===
90
91
92.Request header
93[source, java]
94----
95private static void writeRequestHeader(int reqLength, short opCode, long reqId, DataOutputStream out) throws IOException {
96// Message length
97writeIntLittleEndian(10 + reqLength, out);
98
99// Op code
100writeShortLittleEndian(opCode, out);
101
102// Request id
103writeLongLittleEndian(reqId, out);
104}
105----
106
107
108[cols="1,2",opts="header"]
109|===
110|Response Type | Description
111|int| Length of response message.
112|long| Request id (see above)
113|int| Status code (0 for success, otherwise error code)
114|String| Error message (present only when status is not 0)
115|===
116
117
118
119.Response header
120[source, java]
121----
122private static void readResponseHeader(DataInputStream in) throws IOException {
123// Response length
124final int len = readIntLittleEndian(in);
125
126// Request id
127long resReqId = readLongLittleEndian(in);
128
129// Success code
130int statusCode = readIntLittleEndian(in);
131}
132----
133
134
135== Connectivity
136
137=== TCP Socket
138
139Client applications should connect to server nodes with a TCP socket. By default, the connector is enabled on port 10800. You can configure the port number and other server-side connection parameters in the `clientConnectorConfiguration` property of `IgniteConfiguration` of your cluster, as shown below:
140
141[tabs]
142--
143tab:XML[]
144
145[source, xml]
146----
147<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
148<!-- Thin client connection configuration. -->
149<property name="clientConnectorConfiguration">
150<bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
151<property name="host" value="127.0.0.1"/>
152<property name="port" value="10900"/>
153<property name="portRange" value="30"/>
154</bean>
155</property>
156
157<!-- Other Ignite Configurations. -->
158
159</bean>
160
161----
162
163
164tab:Java[]
165
166[source, java]
167----
168IgniteConfiguration cfg = new IgniteConfiguration();
169
170ClientConnectorConfiguration ccfg = new ClientConnectorConfiguration();
171ccfg.setHost("127.0.0.1");
172ccfg.setPort(10900);
173ccfg.setPortRange(30);
174
175// Set client connection configuration in IgniteConfiguration
176cfg.setClientConnectorConfiguration(ccfg);
177
178// Start Ignite node
179Ignition.start(cfg);
180----
181
182--
183
184=== Connection Handshake
185
186Besides socket connection, the thin client protocol requires a connection handshake to ensure that client and server versions are compatible. Note that handshake must be the first message after the connection is established.
187
188For the handshake message request and response structure, see the <<Handshake>> section above.
189
190
191=== Example
192
193
194.Socket and Handshake Connection
195[source, java]
196----
197Socket socket = new Socket();
198socket.connect(new InetSocketAddress("127.0.0.1", 10800));
199
200String username = "yourUsername";
201
202String password = "yourPassword";
203
204DataOutputStream out = new DataOutputStream(socket.getOutputStream());
205
206// Message length
207writeIntLittleEndian(18 + username.length() + password.length(), out);
208
209// Handshake operation
210writeByteLittleEndian(1, out);
211
212// Protocol version 1.0.0
213writeShortLittleEndian(1, out);
214writeShortLittleEndian(1, out);
215writeShortLittleEndian(0, out);
216
217// Client code: thin client
218writeByteLittleEndian(2, out);
219
220// username
221writeString(username, out);
222
223// password
224writeString(password, out);
225
226// send request
227out.flush();
228
229// Receive handshake response
230DataInputStream in = new DataInputStream(socket.getInputStream());
231int length = readIntLittleEndian(in);
232int successFlag = readByteLittleEndian(in);
233
234// Since Ignite binary protocol uses little-endian byte order,
235// we need to implement big-endian to little-endian
236// conversion methods for write and read.
237
238// Write int in little-endian byte order
239private static void writeIntLittleEndian(int v, DataOutputStream out) throws IOException {
240out.write((v >>> 0) & 0xFF);
241out.write((v >>> 8) & 0xFF);
242out.write((v >>> 16) & 0xFF);
243out.write((v >>> 24) & 0xFF);
244}
245
246// Write short in little-endian byte order
247private static final void writeShortLittleEndian(int v, DataOutputStream out) throws IOException {
248out.write((v >>> 0) & 0xFF);
249out.write((v >>> 8) & 0xFF);
250}
251
252// Write byte in little-endian byte order
253private static void writeByteLittleEndian(int v, DataOutputStream out) throws IOException {
254out.writeByte(v);
255}
256
257// Read int in little-endian byte order
258private static int readIntLittleEndian(DataInputStream in) throws IOException {
259int ch1 = in.read();
260int ch2 = in.read();
261int ch3 = in.read();
262int ch4 = in.read();
263if ((ch1 | ch2 | ch3 | ch4) < 0)
264throw new EOFException();
265return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0));
266}
267
268
269// Read byte in little-endian byte order
270private static byte readByteLittleEndian(DataInputStream in) throws IOException {
271return in.readByte();
272}
273
274// Other write and read methods
275
276----
277
278
279== Client Operations
280
281Upon successful handshake, a client can start performing various cache operations:
282
283* link:binary-client-protocol/key-value-queries[Key-Value Queries]
284* link:binary-client-protocol/sql-and-scan-queries[SQL and Scan Queries]
285* link:binary-client-protocol/binary-type-metadata[Binary-Type Operations]
286* link:binary-client-protocol/cache-configuration[Cache Configuration Operations]
287