In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Today, I will talk to you about how to design message files for gRPC services in A. NET Core, which may not be well understood by many people. in order to make you understand better, the editor has summarized the following contents for you. I hope you can get something according to this article.
How to design messages for gRPC services in A. NET Core
It's easy to define gRPC services using the protocol buffer specification, but there are a few things to keep in mind when switching from requirements to .NET Core and then managing the evolution of services.
At the heart of creating a gRPC service is the .proto file, which describes the service in a language-independent format. Using the .proto file, Visual Studio can generate base classes for your service (you only need to write business-specific code), or you can generate client classes for reliable access to the service.
The .proto file must conform to Google's protocol buffer specification (commonly referred to as ProtoBuf). The contents of the original file allow you to specify the interface of the service. The service interface consists of two parts:
The methods provided by your gRPC service
The data structure of the parameters and return values of these methods
You can use the scalar types defined in the Protocol Buffers specification [1] to build these data structures (called "messages" in ProtoBuf). Available types include Boolean values, strings, byte arrays, and various numeric types (floating point, integer, and long). No date or fixed decimal type. In the next column, I'll show you how to add a timestamp type. For decimals, you can use float... And it is accompanied by the loss of precision brought by float.
If you are starting a new project, use the proto3 syntax since 2016. However, you must explicitly specify the proto3 standard on the first line "non-empty" of the .proto file. Reference the specification [2]), otherwise your .proto file will be parsed using the proto2 specification. Specifying that your file uses proto3 looks like this:
Syntax = "proto3"; messages and C# classes
Using the proto3 specification, the message format for customer information might be as follows:
Message CustomerResponse {int32 custid = 1; string firstName = 2; string lastName = 3; int32 age = 4; fixed32 creditLimit = 5;}
The number after the equal sign specifies the location of the field in the message, starting at location 1 (in my example, firstName will be the second field in the message). These numbers must be unique in the message (that is, you cannot use two fields in the same location). You don't have to list fields in numerical order, but if you do, you can more easily find duplicate field numbers (although Visual Studio will find any duplicate numbers and report them in the "error list" when building your application). You can also skip the position if necessary. This definition uses only odd numbers, for example:
Message CustomerResponse {int32 custid = 1; string firstName = 3; string lastName = 5;}
In .NET Core, the message format is converted to a class, and each field becomes an attribute of a class with the same name as the message. When naming these properties,. NET Core also converts the first character of the field name to uppercase. So, for example, the custId field in my previous example will become the CustId attribute on the CustomerResponse class in my code.
During this process, you also have to remove all underscores in the field name and capitalize the following letters (that is, the Last_name field name becomes the LastName property).
The process also involves mapping .NET types to ProtoBuf types (for example, int64 where ProtoBuf int32 becomes .NET int,ProtoBuf becomes long,fixed32 becomes uint), which requires adding some new classes to the .NET Core. For example, ProtoBuf supports byte arrays with a type of bytes. This field type is supported by a new .NET data type named ByteString. To load ByteString, use the static CopyFrom method of the ByteString class and pass a byte array, as follows:
Byte [] bytes = new byte [1000]; cr.Valid = ByteString.CopyFrom (bytes)
To retrieve a byte array from ByteString, use the object's CopyTo method and pass the array and starting position to copy the bytes to:
Cr.Valid.CopyTo (bytes,0); arrays and dictionaries
You can also use the keyword [repeated] to include the collection in the definition (in ProtoBuf, fields that are not collections are called "singular"). If my customer message requires a duplicate set of transaction amounts, you can specify the following fields:
Message Customer {int32 id = 1; repeated fixed32 transactionAmounts = 4
Duplicate fields also use the new type: Google.Protobuf.RepeatedField when converting to properties of the class. For example, my example will generate attributes of Google.Protobuf.RepeatedField (unsigned integers). You can initialize the array using the {} syntax, as follows:
CustomerResponse cr = new CustomerResponse {CreditLimit = {10,15,100}}
You are more likely to use its various Add methods to put items into a collection:
Cr.CreditLimit.Add (200)
You can use the LINQ method (such as First ()) or access the project in RepeatedField by location. Can work properly, for example:
Uint tranAmount = cr.CreditLimit [1]
ProtoBuf also supports a Dictionary-type collection called map, which allows you to specify types for keys and values of dictionaries. My customer messages may use "friendly names" to track customers' various credit cards to define a dictionary that contains strings of keys ("Peter card", "my travel card") and values (credit card number):
Message CustomerResponse {int32 custId = 1; map cards = 2
Interestingly, in the Visual Studio 2019 preview, the editor does not highlight map objects like other types (although compiled well).
The corresponding property will be of type Google.Protobuf.Collections.MapField, which you can load by passing its Add method to the key and a value, just like any other Dictionary.
Manage Chan
It is relatively easy to change the .proto file after it is launched (and the client starts to use it). For example, you can add fields with a new location number to the .proto file used by the server-side software without disturbing clients that are still using earlier versions of the file: the client simply ignores fields that are not listed in its .proto file.
Similarly, in the opposite case (when the server .proto file does not have a field in the client's .proto field), the client will only find that the properties not sent by the server are set to their default values. By the way, fields defined in the server's .proto file and not defined in the client's .proto file are still sent to the client, but .NET does not provide a convenient way to access it (at least not yet).
Indeed, as the service evolves and modifies its .proto file, you should follow only two rules:
Do not change the location number of an existing field
Do not recycle the position number (that is, do not replace the outdated field 3 with the new field 3)
However, a property generated from a .proto file cannot be empty, so if the property is not set to a value, it will be set to its default value. This means that the number is set to 0; the number is set to 0. Set string to string.Empty (a string of zero length); Boolean becomes false; the ByteString property defaults to the ByteString object, its IsEmpty property is set to true;, and the RepeatedField and MapField properties default to its corresponding object, each object contains no items, and its Count property is set to 0.
Because of this behavior, there is a risk of removing fields from the service's .proto file and not updating all clients (or simply not setting properties on the object when the response is generated on the server). The danger is that the client cannot distinguish between unused fields and properties that have been set to their default values. If you set the valid property of my customer to false, the client will not be able to determine whether the customer is invalid or whether the server will no longer generate this field.
You may want to consider initializing the property to an "unreasonable" value (for example, the number is-1) so that the client can tell the difference between the property set as the default value and the deleted field. Because this is not possible for Boolean values (Boolean values do not have unreasonable values), you should be particularly careful to delete (or even no longer use) Boolean fields.
Efficiency and limitation
As I discussed in my earlier overview [3] [4], one of the functions of gRPC services is that their messages are much smaller than HTTP-based (RESTful) services. If you really want to take advantage of this efficiency, note that locations 1 to 15 require only one byte of additional overhead (that is, data that exceeds the stored value), while locations 16 to 2047 require two bytes. Keeping the message format below 16 bits seems like a good idea.
For other efficiency tips on choosing a type to package data into the smallest possible space, see the scalar type description [5] in the specification.
By the way, you can't use any of the following as field location numbers: negative numbers, 0, 19000 to 19999 (reserved for ProtoBuf), or numbers greater than 536870911.
After reading the above, do you have any further understanding of how to design message files for gRPC services in A. NET Core? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.