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://walker-learn.xyz/archives/4772

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

Related Posts

  • Nuxt3: Beginner's Guide and Principles Introduction [Learning Notes]

    Nuxt 3: Getting Started and Principles 💡 What is Nuxt 3? Nuxt 3 is a full-stack frontend framework built on Vue 3 and Vite, supporting: Server-Side Rendering (SSR) Static Site Generation (SSG) Single-Page Applications (SPA) Building full-stack applications (with API support) Nuxt 3 is an "enhanced version" of Vue, helping you simplify project structure and development workflow. 🔧 Core Principles Feature How Nuxt Handles It ✅ Page Routing Automatic root...

    Personal Apr 6, 2025
    2.1K00
  • From 0 to 1: Implementing Micro-frontend Architecture 001 [Study Notes]

    Micro-frontends, JS isolation, CSS isolation, element isolation, lifecycle, preloading, data communication, application navigation, multi-level nesting. Note: This uses Mermaid's flowchart syntax, which is supported by Markdown renderers such as Typora, VitePress, and some Git platforms. Retained: Host application main-vue3; child applications: child-nuxt2-home, child-vue2-job, child-vu...

    Apr 20, 2025
    1.5K00
  • Go Engineer Comprehensive Course 006 [Study Notes]

    Project Structure Description: The user-web module is the user service Web layer module within the joyshop_api project, responsible for handling user-related HTTP requests, parameter validation, business routing, and calling backend interfaces. Below is the directory structure description: user-web/ ├── api/ # Controller layer, defines business interface processing logic ├── config/ # Configuration module, contains system configuration structs and reading logic ...

    Personal Nov 25, 2025
    21400
  • In-depth Understanding of ES6 013 [Study Notes]

    Code Encapsulation with Modules

    JavaScript loads code using a "share everything" approach to loading code, which is one of the most error-prone and confusing aspects of the language. Other languages use concepts like packages to define code scope. Before ES6, everything defined in every JavaScript file within an application shared a single global scope. As web applications became more complex and the amount of JavaScript code grew, this practice led to issues such as naming conflicts and security concerns. One of ES6's goals was to address the scoping issue…

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

    Destructuring: Making data access more convenient. If you declare variables using `var`, `let`, or `const` with destructuring, you must provide an initializer (i.e., the value on the right side of the equals sign). The following will cause an error:
    // Syntax error `var {tyep,name}`
    // Syntax error `let {type,name}`
    // Syntax error `const {type,name}`
    To assign values to already declared variables using destructuring, consider the following:
    `let node = { type:&qu...`

    Personal Mar 8, 2025
    1.2K00
EN
简体中文 繁體中文 English
欢迎🌹 Coding never stops, keep learning! 💡💻 光临🌹