Getting Started with the GRPC component
Requirements: IPWorks
The GRPC component is designed to send and receive messages over gRPC. The component can be used to both create message to send as well as read incoming messages.
Contents
Reading Messages
To read an incoming message, listen to the MessageIn event. The MessageIn event will fire for each message from the server. For each message the MessageData property will be populated with the raw message from the server. The component can be used to read the messages in a structured way.
There are two ways of reading an incoming message. The message can be navigated using the XPath property, or by sequentially reading the values in the message. By providing multiple ways to read a message you can choose which best suits your needs.
This is an example .proto file which will be used for demonstration throughout this article:
syntax = "proto3";
message Types {
string name = 1;
int32 num32 = 2;
int64 num64 = 3;
Types subRequest = 4;
repeated int32 repeatVarInt = 5;
}
XPath Syntax
XPath provides a simple way to navigate the fields within the received message using a subset of the XML XPath specification. The XPath property may be set to navigate to a specific field within the message structure. The HasXPath method may be used to determine if an XPath exists before setting navigating to the location. The TryXPath method will attempt to navigate to the specified path and return true or false depending on the result.
XPath may be set to a series of one or more field accessors separated by '/'. The path can be absolute (starting with '/') or relative to the current XPath location. After setting the XPath property use any of the following methods to read data or information about the field at the selected path.
- ReadBool
- ReadBytes
- ReadDouble
- ReadFieldNumber
- ReadFixed32
- ReadFixed64
- ReadFloat
- ReadInt32
- ReadInt64
- ReadString
The following are possible values for a field accessor:
field_number | The integer number of the field, for instance /2 or /11. |
field_number[i] | The i-th occurrence of the field specified by field_number, for instance /2[1] or /11[3] |
[index] | The field at the position specified by index. For instance /[2] would select the second field, regardless of the field number |
. | The current location |
.. | The parent of the current location |
Nested Messages
When a field of a message is itself another message, the fields of the sub-message may be accessed by constructing an XPath to point to the sub-message field. For instance /5/4 would move to field number 5 in the top level message (which is itself a message), and then field number 4 of the sub-message.
Packed Repeated Fields
Example syntax for accessing values within packed repeated fields is shown below. The type of value within the packed repeated field must be known ahead of time. The XCount property can be used to obtain the number of values within the packed repeated field.
/10#v | Select field number 10 which is a packed repeated field of type varint |
/11#i | Select field number 11 which is a packed repeated field of type fixed32 |
/12#l | Select field number 12 which is a packed repeated field of type fixed64 |
/10#v[2] | Select the 2nd value of field number 10 which is a packed repeated field of type varint |
/11#v[2] | Select the 2nd value of field number 11 which is a packed repeated field of type fixed32 |
/12#v[2] | Select the 2nd value of field number 12 which is a packed repeated field of type fixed64 |
For instance to iterate through all values of the Type message specified in the example .proto file above using XPath:
gRPC.XPath = "/1"; // name
string name = gRPC.ReadString(); // reads the string value for name
gRPC.XPath = "/2"; // num32
int num32 = gRPC.ReadInt32(); // reads the int value for num32
gRPC.XPath = "/4/3"; // num64 of subRequest
long num64 = gRPC.ReadInt64(); // reads the int64 value for the num64 field of subRequest
gRPC.XPath = "/5#v"; // repeatVarInt
int count = gRPC.XCount;
for(int i=0;i < count;i++) {
gRPC.XPath = "/5#v[ " + i.ToString() + "]"; // sets the index
Console.WriteLine(Int32.Parse(gRPC.ReadInt32())); // reads the int32 field
}
Sequential Reads
An alternative to using the XPath property is sequentially reading each field within the message. This is done by making use of the MessageIn event and the Read* methods to read the fields of the message sequentially.
In order to read a message sequentially, first call BeginReadMessage. Next, call ReadFieldNumber to get the next field number. The component will automatically move to the next field number to read. Then call the appropriate method from the list below to read the field value:
- ReadString
- ReadInt32
- ReadInt64
- ReadFloat
- ReadFixed32
- ReadFixed64
- ReadDouble
- ReadBytes
- ReadBool
Read message example for the Type message specified in the example .proto file above:
// Begins reading the message
grpc.BeginReadMessage();
// Gets the field number for name
String CurrentFieldNumber = grpc.ReadFieldNumber();
// Gets the string value of field with field number 1(name)
String name = grpc.ReadString();
// Gets the next field number(num32)
CurrentFieldNumber = grpc.ReadFieldNumber();
// Gets the int32 value of the field num32
int num32 = grpc.ReadInt32();
// Skips the next field number(num64)
grpc.ReadSkip();
// Gets the next field number(subRequest)
CurrentFieldNumber = grpc.ReadFieldNumber();
// Begins reading the subRequest field
grpc.BeginReadMessage();
int CurrentSubRequestFieldNumber = grpc.ReadFieldNumber();
String nameSubRequest = grpc.ReadString();
// Ends reading the subRequest field
grpc.EndReadMessage();
// Ends reading the message
grpc.EndReadMessage();
If the field you want to read is a packed repeated field, then before calling any of the methods mentioned, call BeginReadPacked. BeginReadPacked returns the count of the repeated values. Call the ReadInt32 method to sequentially read each packed value. When done reading the packed repeated values, call EndReadPacked.
Read example of the packed repeated field named repeatVarInt in the example .proto file above:
// Begins reading the message
grpc.BeginReadMessage();
// Skip 4 times to reach the packed repeated field(repeatVarInt)
grpc.ReadSkip();
grpc.ReadSkip();
grpc.ReadSkip();
grpc.ReadSkip();
// Gets the field number for the current field to read
String CurrentFieldNumber = grpc.ReadFieldNumber();
// Gets the count of the packed repeated field
int count = grpc.BeginReadPacked(0);
int[] theValues = new int[count];
for(int i=0 ;i < count; i++) {
// Get the values and store them in the theValues array
theValues[i] = grpc.ReadInt32();
}
// Ends reading a packed repeated field
grpc.EndReadPacked();
// Ends reading a message
grpc.EndReadMessage();
After all the fields of the message are read, call EndReadMessage.
Writing Messages
The GRPC component can also be used to construct a new message. Message can be written sequentially, one field at a time. The message can then be sent through gRPC by using the Post method.
In order to write a message, first call BeginWriteMessage. Next, call WriteFieldNumber and pass the field number to write. Then call the appropriate method from the list below to write the field value.
- WriteString
- WriteInt32
- WriteInt64
- WriteFloat
- WriteFixed32
- WriteFixed64
- WriteDouble
- WriteBytes
- WriteBool
Write example for the Type message specified in the example .proto above:
// Begins writing a new message
grpc.BeginWriteMessage();
// Specifies the field number for the current field to write(name)
grpc.WriteFieldNumber(1);
// Specifies the value of field with field number 1
grpc.WriteString("test");
grpc.WriteFieldNumber(2); //num32
grpc.WriteInt32(2);
// Ends writing a message
grpc.EndWriteMessage();
To write a packed repeated field call BeginWritePacked. Then call the appropriate method from above to write the packed repeated values. Finish by calling the EndWritePacked method.
Write example of the packed repeated field named repeatedVarInt in the example .proto above:
int[] RepeatedVarInt = new int[] { 3, 270, 86942 };
// Begins writing a new message
grpc.BeginWriteMessage();
//Specifies the field number for the current field to write(repeatedVarInt)
grpc.WriteFieldNumber(5);
// Begins writing the packed repeated field
grpc.BeginWritePacked();
for(int i=0 ;i < RepeatedVarInt.Length; i++) {
// Write each packed value
grpc.WriteInt32(RepeatedVarInt[i]);
}
// Ends writing a packed repeated field
grpc.EndWritePacked();
// Ends writing a new message
grpc.EndWriteMessage();
As a last step call EndWriteMessage.
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.