Go Engineering Systematic Course 003 [Study Notes]

grpc grpc grpc-go grpc seamlessly integrates protobuf protobuf. For those of you accustomed to using JSON and XML data storage formats, I believe most have never heard of Protocol Buffer. Protocol Buffer is actually a lightweight & efficient structured data storage format developed by Google, and its performance is truly much, much stronger than JSON and XML! protobuf…

grpc

  • grpc
  • grpc-go

gRPC seamlessly integrates Protobuf.

protobuf

  • For those accustomed to JSON and XML data storage formats, I believe most of you haven't heard of Protocol Buffer.
  • Protocol Buffer is actually a lightweight & efficient structured data storage format developed by Google, and its performance is truly much stronger than JSON and XML!
  • Protobuf has gone through protobuf2 and protobuf3, with pb3 being significantly simplified compared to pb2. The current mainstream version is pb3.

Downloading protoc

Download protoc andgo get github.com/golang/protobuf/protoc-gen-go

syntax = "proto3";

option go_package = "."; //这名不写现在编译不了

message HelloRequest {
  string name = 1; //1 是编号不是值
}
protoc --proto_path=. \
  --go_out=. \
  --go-grpc_out=. \
  ./helloworld.proto

This will generate ahelloworld.pb.gofile in the directory.

Comparison of compression ratios

package main

import (
 "RpcLearn/protobuf"
 "encoding/json"
 "fmt"
 "github.com/golang/protobuf/proto"
)

// TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>
type Hello struct {
 Name string `json:"name"`
}

func main() {
 //TIP <p>Press <shortcut actionId="ShowIntentionActions"/> when your caret is at the underlined text
 // to see how GoLand suggests fixing the warning.</p><p>Alternatively, if available, click the lightbulb to view possible fixes.</p>
 //s := "gopher"
 //fmt.Printf("Hello and welcome, %s!\n", s)
 //
 //for i := 1; i <= 5; i++ {
 // //TIP <p>To start your debugging session, right-click your code in the editor and select the Debug option.</p> <p>We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
 // // for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.</p>
 // fmt.Println("i =", 100/i)
 //}
 jsonStruct := Hello{
  Name: "gopher",
 }
 jsonReq, _ := json.Marshal(jsonStruct)
 fmt.Println(string(jsonReq))
 fmt.Println(len(jsonReq))
 req := __.HelloRequest{
  Name: "gopher",
 }
 rsp, _ := proto.Marshal(&req)
 fmt.Println(rsp)
 fmt.Println(len(rsp))

}

Approximately a twofold difference.

Explanation of Changes in Using Protobuf with Go Language

Tutorial Content Current Reality
Previously, there was only one .pb.go file. Now, two files are generated: one .pb.go (data structure) and one _grpc.pb.go (gRPC interface).
Plugins not separated Plugins have been split into protoc-gen-go and protoc-gen-go-grpc, requiring separate installation and invocation.

📌 Current Behavior Explanation

Starting from Go's Protobuf plugin v1.20+, gRPC support has been split into a separate plugin, protoc-gen-go-grpc, used to generate service interface-related code. This approach is more modular and has clearer responsibilities.

Therefore, execute the following command:

protoc --proto_path=. \
  --go_out=. \
  --go-grpc_out=. \
  ./your_file.proto

This will generate:

  • your_file.pb.go: Contains message structures (e.g., Request, Response)
  • your_file_grpc.pb.go: Contains service interface definitions (e.g., YourServiceServer)

It is recommended to retain and synchronize these two files.

Briefly Outline the gRPC Startup Process

  1. Create stub files and method definitions, then compile.
// proto/helloworld.proto
syntax = "proto3";
option go_package = ".;proto";

service Greeter{
    rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
    string name = 1;
}
message HelloReply {
    string message = 1;
}
  1. The server-side implements the call to the defined method, noting the server implementation (duck typing).
package main

import (
 "RpcLearn/grpc_test/proto"
 "context"
 "google.golang.org/grpc"
 "log"
 "net"
)

type Server struct {
 proto.UnimplementedGreeterServer // 👈 重点:嵌入这个类型
}

func (s *Server) SayHello(ctx context.Context, req *proto.HelloRequest) (*proto.HelloReply, error) {
 reply := &proto.HelloReply{
  Message: "Hello " + req.Name,
 }
 return reply, nil
}

func main() {
 g := grpc.NewServer()                     // 创建一个新的gRPC服务器
 proto.RegisterGreeterServer(g, &Server{}) // 注册服务
 listener, err := net.Listen("tcp", ":9090")
 if err != nil {
  log.Fatalf("failed to listen: %v", err)
 }
 err = g.Serve(listener)
 if err != nil {
  log.Fatalf("failed to serve: %v", err)
 }
}
  1. Client-side call implementation.
package main

import (
 "RpcLearn/grpc_test/proto"
 "context"
 "fmt"
 "google.golang.org/grpc"
 "google.golang.org/grpc/credentials/insecure"
)

func main() {
 // Create a new gRPC server
 //conn, err := grpc.Dial("localhost:9090", grpc.WithInsecure())
 // 使用安全连接
 //creds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
 conn, err := grpc.NewClient("localhost:9090",
  //grpc.WithInsecure()
  grpc.WithTransportCredentials(insecure.NewCredentials()), // ✅ 新方式
 )
 if err != nil {
  panic(err)
 }
 defer conn.Close()
 c := proto.NewGreeterClient(conn)
 r, err := c.SayHello(context.Background(), &proto.HelloRequest{Name: "world"})
 if err != nil {
  panic(err)
 }
 fmt.Println(r.Message)

}

gRPC Stream Method (Streaming Mode)

  1. Simple mode (simple RPC)
  2. Server-side data stream
  3. Client-side data stream
  4. Bidirectional

Focused Learning on gRPC

Protobuf Type Go Type
double float64
float float32
int32 int32
int64 int64
uint32 uint32
uint64 uint64
sint32 int32
sint64 int64
fixed32 uint32
fixed64 uint64

Default values

Default Value Explanation

In Protobuf, different field types have the following default values:

  • String type (string): The default value is an empty string.
  • Byte type (bytes): The default value is an empty byte sequence.
  • Boolean type (bool): The default value is false.
  • Numeric types (number types): The default value is 0.
  • Enum type: The default value is the first defined enum value, and it must be 0.
  • Message type (message): The default value is unset (i.e., null).

Notes

  1. For scalar message fields: Once a message is parsed, it's impossible to distinguish whether a field was set to its default value (

    主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://www.walker-learn.xyz/archives/4772

(0)
Walker的头像Walker
上一篇 Nov 25, 2025 03:00
下一篇 Nov 25, 2025 01:00

Related Posts

  • Go Engineer System Course 007 [Study Notes]

    Goods Microservice Entity Structure Description This module contains the following core entities: Goods (Goods) Goods Category (Category) Brand (Brands) Carousel (Banner) Goods Category Brand (GoodsCategoryBrand) 1. Goods (Goods) Describes the product information actually displayed and sold on the platform. Field Description Field Name Type Description name String Product name, required brand Pointer …

    Personal Nov 25, 2025
    30700
  • Deep Dive into ES6 010 [Study Notes]

    Improved array functionality. The peculiar behavior of `new Array()`: when a single numeric value is passed to the constructor, the array's `length` property is set to that value; if multiple values are passed, regardless of whether they are numeric or not, they all become elements of the array. This behavior is confusing, as it's not always possible to pay attention to the type of data passed in, thus posing a certain risk. `Array.of()`, regardless of how many arguments are passed, has no special case for a single numeric value (one argument and numeric type); it always returns an array containing all arguments...

    Personal Mar 8, 2025
    1.3K00
  • In-depth Understanding of ES6 001 [Study Notes]

    Block-Level Scope Binding
    Previously, `var` variable declarations, regardless of where they were declared, were considered to be declared at the top of their scope. Since functions are first-class citizens, the typical order was `function functionName()`, followed by `var variable`.

    Block-Level Declarations
    Block-level declarations are used to declare variables that cannot be accessed outside the scope of a specified block. Block-level scope exists in:
    - Inside functions
    - Within blocks (the region between `{` and `}`)

    Temporal Dead Zone
    When the JavaScript engine scans code and finds variable declarations, it either hoists them to the top of the scope...

    Personal Mar 8, 2025
    1.8K00
  • Go Engineer Comprehensive Course: protoc-gen-validate Study Notes

    protoc-gen-validate: Introduction and Usage Guide ✅ What is protoc-gen-validate? protoc-gen-validate (PGV for short) is a Protocol Buffers plugin used to add validation logic for struct fields in generated Go code. It automatically generates validation code for each field by adding validation rules in .proto files, saving you the trouble of manually...

    Personal Nov 25, 2025
    1.4K00
  • In-depth Understanding of ES6 009 [Learning Notes]

    Classes in JavaScript function PersonType(name){ this.name = name; } PersonType.prototype.sayName = function(){ console.log(this.name) } var person = new PersonType("Nicholas") p…

    Personal Mar 8, 2025
    1.3K00
EN
简体中文 繁體中文 English