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`.