github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/Documentation/encoding.md (about)

     1  # Encoding
     2  
     3  The gRPC API for sending and receiving is based upon *messages*.  However,
     4  messages cannot be transmitted directly over a network; they must first be
     5  converted into *bytes*.  This document describes how gRPC-Go converts messages
     6  into bytes and vice-versa for the purposes of network transmission.
     7  
     8  ## Codecs (Serialization and Deserialization)
     9  
    10  A `Codec` contains code to serialize a message into a byte slice (`Marshal`) and
    11  deserialize a byte slice back into a message (`Unmarshal`).  `Codec`s are
    12  registered by name into a global registry maintained in the `encoding` package.
    13  
    14  ### Implementing a `Codec`
    15  
    16  A typical `Codec` will be implemented in its own package with an `init` function
    17  that registers itself, and is imported anonymously.  For example:
    18  
    19  ```go
    20  package proto
    21  
    22  import "github.com/hxx258456/ccgo/grpc/encoding"
    23  
    24  func init() {
    25  	encoding.RegisterCodec(protoCodec{})
    26  }
    27  
    28  // ... implementation of protoCodec ...
    29  ```
    30  
    31  For an example, gRPC's implementation of the `proto` codec can be found in
    32  [`encoding/proto`](https://godoc.org/google.golang.org/grpc/encoding/proto).
    33  
    34  ### Using a `Codec`
    35  
    36  By default, gRPC registers and uses the "proto" codec, so it is not necessary to
    37  do this in your own code to send and receive proto messages.  To use another
    38  `Codec` from a client or server:
    39  
    40  ```go
    41  package myclient
    42  
    43  import _ "path/to/another/codec"
    44  ```
    45  
    46  `Codec`s, by definition, must be symmetric, so the same desired `Codec` should
    47  be registered in both client and server binaries.
    48  
    49  On the client-side, to specify a `Codec` to use for message transmission, the
    50  `CallOption` `CallContentSubtype` should be used as follows:
    51  
    52  ```go
    53  	response, err := myclient.MyCall(ctx, request, grpc.CallContentSubtype("mycodec"))
    54  ```
    55  
    56  As a reminder, all `CallOption`s may be converted into `DialOption`s that become
    57  the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`:
    58  
    59  ```go
    60  	myclient := grpc.Dial(ctx, target, grpc.WithDefaultCallOptions(grpc.CallContentSubtype("mycodec")))
    61  ```
    62  
    63  When specified in either of these ways, messages will be encoded using this
    64  codec and sent along with headers indicating the codec (`content-type` set to
    65  `application/grpc+<codec name>`).
    66  
    67  On the server-side, using a `Codec` is as simple as registering it into the
    68  global registry (i.e. `import`ing it).  If a message is encoded with the content
    69  sub-type supported by a registered `Codec`, it will be used automatically for
    70  decoding the request and encoding the response.  Otherwise, for
    71  backward-compatibility reasons, gRPC will attempt to use the "proto" codec.  In
    72  an upcoming change (tracked in [this
    73  issue](https://github.com/grpc/grpc-go/issues/1824)), such requests will be
    74  rejected with status code `Unimplemented` instead.
    75  
    76  ## Compressors (Compression and Decompression)
    77  
    78  Sometimes, the resulting serialization of a message is not space-efficient, and
    79  it may be beneficial to compress this byte stream before transmitting it over
    80  the network.  To facilitate this operation, gRPC supports a mechanism for
    81  performing compression and decompression.
    82  
    83  A `Compressor` contains code to compress and decompress by wrapping `io.Writer`s
    84  and `io.Reader`s, respectively.  (The form of `Compress` and `Decompress` were
    85  chosen to most closely match Go's standard package
    86  [implementations](https://golang.org/pkg/compress/) of compressors.  Like
    87  `Codec`s, `Compressor`s are registered by name into a global registry maintained
    88  in the `encoding` package.
    89  
    90  ### Implementing a `Compressor`
    91  
    92  A typical `Compressor` will be implemented in its own package with an `init`
    93  function that registers itself, and is imported anonymously.  For example:
    94  
    95  ```go
    96  package gzip
    97  
    98  import "github.com/hxx258456/ccgo/grpc/encoding"
    99  
   100  func init() {
   101  	encoding.RegisterCompressor(compressor{})
   102  }
   103  
   104  // ... implementation of compressor ...
   105  ```
   106  
   107  An implementation of a `gzip` compressor can be found in
   108  [`encoding/gzip`](https://godoc.org/google.golang.org/grpc/encoding/gzip).
   109  
   110  ### Using a `Compressor`
   111  
   112  By default, gRPC does not register or use any compressors.  To use a
   113  `Compressor` from a client or server:
   114  
   115  ```go
   116  package myclient
   117  
   118  import _ "github.com/hxx258456/ccgo/grpc/encoding/gzip"
   119  ```
   120  
   121  `Compressor`s, by definition, must be symmetric, so the same desired
   122  `Compressor` should be registered in both client and server binaries.
   123  
   124  On the client-side, to specify a `Compressor` to use for message transmission,
   125  the `CallOption` `UseCompressor` should be used as follows:
   126  
   127  ```go
   128  	response, err := myclient.MyCall(ctx, request, grpc.UseCompressor("gzip"))
   129  ```
   130  
   131  As a reminder, all `CallOption`s may be converted into `DialOption`s that become
   132  the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`:
   133  
   134  ```go
   135  	myclient := grpc.Dial(ctx, target, grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
   136  ```
   137  
   138  When specified in either of these ways, messages will be compressed using this
   139  compressor and sent along with headers indicating the compressor
   140  (`content-coding` set to `<compressor name>`).
   141  
   142  On the server-side, using a `Compressor` is as simple as registering it into the
   143  global registry (i.e. `import`ing it).  If a message is compressed with the
   144  content coding supported by a registered `Compressor`, it will be used
   145  automatically for decompressing the request and compressing the response.
   146  Otherwise, the request will be rejected with status code `Unimplemented`.