最近较忙,其实准备一篇搞定的
中途有事,只能隔了一天再写

正文

pb.go

需要注意的是,在本个 demo 中,客户端与服务端都是 Golang,所以在客户端与服务端都公用一个 pb.go 模板文件(如果是不同的语言生成的pb是对应语言),可以将 pb.go 文件放置在云上由双方引用,也可以生成两个副本放在两端项目中,本次就使用 COPY 两份的方式
由于 Golang 一个文件夹只有一个 package,而生成的 pb.go 文件 package 为创建 proto 的名字(示例为 spider), 所以我们在项目内单独建立文件夹 spider将文件放入其中即可正常使用

编写 server 端

编写 main.go 文件

package main

import (
	"context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
	"io/ioutil"
	"net"
	"net/http"
	"server/spider"
)

type server struct{}

const (
	// Address 监听地址
	Address string = "localhost:8080"
	// Method 通信方法
	Method string = "tcp"
)

// 接收client端的请求,函数名需保持一致
// ctx参数必传
// 参数二为自定义的参数,需从pb文件导入,因此pb文件必须可导入,文件放哪里随意
// 返回值同参数二,为pb文件的返回结构体指针
func (s *server) GetAddressResponse(ctx context.Context, a *spider.SendAddress) (*spider.GetResponse, error) {
	// 逻辑写在这里
	switch a.Method {
	case "get", "Get", "GET":
		// 演示微服务用,故只写get示例
		status, body, err := get(a.Address)
		if err != nil {
			return nil, err
		}
		res := spider.GetResponse{
			HttpCode: int32(status),
			Response: body,
		}
		return &res, nil
	}
	return nil, nil
}

func get(address string) (s int, r string, err error) {
	// get请求
	resp, err := http.Get(address)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	s = resp.StatusCode
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return
	}
	r = string(body)
	return
}

func main() {
	// 监听本地端口
	listener, err := net.Listen(Method, Address)
	if err != nil {
		return
	}
	s := grpc.NewServer()                       // 创建GRPC
	spider.RegisterGoSpiderServer(s, &server{}) // 在GRPC服务端注册服务

	reflection.Register(s) // 在GRPC服务器注册服务器反射服务
	// Serve方法接收监听的端口,每到一个连接创建一个ServerTransport和server的grroutine
	// 这个goroutine读取GRPC请求,调用已注册的处理程序进行响应
	err = s.Serve(listener)
	if err != nil {
		return
	}
}

编写 client 端

package main

import (
	"client/spider"
	"context"
	"google.golang.org/grpc"
)

import "fmt"

const (
	// Address server端地址
	Address string = "localhost:8080"
)

func main() {
	// 连接服务器
	conn, err := grpc.Dial(Address, grpc.WithInsecure())
	if err != nil {
		fmt.Println(err)
		return
	}
	defer conn.Close()

	// 连接GRPC
	c := spider.NewGoSpiderClient(conn)
	// 创建要发送的结构体
	req := spider.SendAddress{
		Address: "http://www.baidu.com",
		Method:  "get",
	}
	// 调用server的注册方法
	r, err := c.GetAddressResponse(context.Background(), &req)
	if err != nil {
		fmt.Println(err)
		return
	}
	// 打印返回值
	fmt.Println(r)
}

运行

需要先启动 server 端监听端口,再启动 client 端向端口发送请求
我们运行后可看到结果已经正常返回并打印
Go GRPC 入门(二)

相关文章: