Sending/Receiving Protobuf Messages¶
The process of sending and receiving a message differs between the TCP and WebSocket standards. Below, we explain this process in detail for both types of connections.
Using TCP¶
Sending a Message¶
To send a message via a TCP connection, do the following.
-
Change the Protobuf message to an array of bytes (using the Protobuf encoding) by using the official Google Protocol Buffer SDK for your chosen programming language.
-
Get the length of the array created during Step 1. Create a new byte array created from this integer. Reverse the new byte array.
-
Concatenate the new byte array and the byte array containing the original Protobuf message.
-
Send the concatenated array to the connection stream.
The examples below demonstrate how these steps are performed in the official Open API SDKs.
1 2 3 4 5 6 7 |
|
1 2 3 |
|
The Python Example
Using Twisted, the Python example performs nearly the same operations as the C# one. The client.send(request)
can be explained as follows.
1 2 3 |
|
Protocol.transport.write()
method. Reading a Message¶
Asynchronous Code
All Open API SDKs rely on asynchronous execution, meaning that they do not wait for messages to arrive but, instead, react to dynamically arriving messages. As a rresult, receiving a message is typically done via event handlers
To read a message, you will have to perform a sequence of actions that reverses the steps required for sending a message.
-
Receive the first four bytes of a byte array (remember, they denote the message length). Reverse these four bytes and change them to an integer.
-
Read
X
amount of bytes from a stream whereX
is the integer you have gotten during Step 1. -
Use the Google Protobuf SDK to deserialize the message into a valid
ProtoMessage
. -
Use the
payloadType
field of theProtoMessage
object to find its actual type. Via the Google Protobuf SDK, change theProtoMessage
to an object of the neededProtoOA...
type.
The code snippets below demonstrate how the official Open API SKDs approach reading messages.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
|
!!! "The Python Example" In the Python example, all operations with bytes on receiving messages are handled by the dataReceived()
method as shown below.
```python linenums="1"
def dataReceived(self, recd):
"""
Convert int prefixed strings into calls to stringReceived.
"""
self.recvd = self.recvd + recd
while len(self.recvd) >= self.prefixLength and not self.paused:
length ,= struct.unpack(
self.structFormat, self.recvd[:self.prefixLength])
if length > self.MAX_LENGTH:
self.lengthLimitExceeded(length)
return
if len(self.recvd) < length + self.prefixLength:
break
packet = self.recvd[self.prefixLength:length + self.prefixLength]
self.recvd = self.recvd[length + self.prefixLength:]
self.stringReceived(packet)
```
1 2 3 4 5 6 7 8 |
|
Using WebSocket¶
Sending a Message¶
To send a message over a WebSocket connection, perform the following actions.
-
Serialize the message into any suitable data format (e.g., a string).
-
Add the serialized message to your send queue.
The examples below demonstrate how these actions are performed in the official Open API SDKs.
The C# SDK uses the WebsocketClient
class which is a part of the Websocket.Client
package. As shown below, the WebsocketClient.Send()
method works as follows.
1 2 3 4 5 |
|
As you can see, the client simply adds an array segment to the send queue.
The Python SDK does not support the WebSocket standard.
Receiving a Message¶
To receive a message over a WebSocket connection, do the following.
-
Retrieve the data received from the cTrader backend.
-
Deserialize data into a valid Protobuf message.
For an illustration of how this is done in the official Open API SDKs, see the below snippets.
To receive messages, a WebsocketClient
needs to be subscribed to a callback function that handles what the client does on accepting a new message.
1 2 |
|
Before subscribing, the .NET SDK parses the message into a Protobuf message. The necessary subscriptions are added in the body of the ConnectWebSocket()
callback.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
In the OnNext()
callback, the ProtoMessage
is passed to the MessageFactory.GetMessage()
callback.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
The Python SDK does not support the WebSocket standard.