到底是Go+还是狗屁?-- 运行一个简单的Grpc

到底是Go+还是狗屁?-- 运行一个简单的Grpc,第1张

文章目录 运行一个简单的Grpc依赖包安装什么是go.mod?设置代理设置自动获取依赖初始化模块 引用项目文件grpc 客户端示例grpc 服务端示例 运行结果


运行一个简单的Grpc

前面我们成功的安装了Go+运行环境,下面我们通过运行一个简单的Grpc来了解下如何进行包的引用。
运行一个简单的Grpc完整地址

依赖包安装

对于依赖库的引用 Go+ 已经做了很多优化让代码写起来更简单,就像前面执行打印时Go需要import "fmt"才可以调用,Go+可以直接调用println函数。但是除了基础外在日常开发中还是需要用到很多外部依赖库,还更便捷的进行开发工作,下面来了解下Go包管理工具go.mod。

什么是go.mod?

Go.mod是Golang1.11版本新引入的官方包管理工具用于解决之前没有地方记录依赖包具体版本的问题,方便依赖包的管理。

Go.mod其实就是一个Modules,关于Modules的官方定义为:

Modules是相关Go包的集合,是源代码交换和版本控制的单元。go命令直接支持使用Modules,包括记录和解析对其他模块的依赖性。Modules替换旧的基于GOPATH的方法,来指定使用哪些源文件。

Modules和传统的GOPATH不同,不需要包含例如src,bin这样的子目录,一个源代码目录甚至是空目录都可以作为Modules,只要其中包含有go.mod文件。

设置代理

执行go get 或 go install 安装依赖时可能会出现地址无法访问的情况,可以设置代理地址,在win10任务栏左下角的win标志右键,以管理员身份打开powershell

$env:GOPROXY = "https://goproxy.io"

如果还是无法访问,还需要设置下外网的代理

set http_proxy=127.0.0.1:19180
set https_proxy=127.0.0.1:19180
设置自动获取依赖

go env -w GO111MODULE=auto

GO111MODULE有三个值:off, on和auto(默认值)。
GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
当前目录在GOPATH/src之外且该目录包含go.mod文件
当前文件在包含go.mod文件的目录下面。

初始化模块

测试项目目录结构如下图所示:

在根目录执行go mod {包名称} 命令后会生成一个go.mod文件,后面这个文件会记录项目使用的包和包版本,有点像Python中的requirements.txt文件。
go.mod 文件

module hello

go 1.17

注意:子目录里是不需要init的,所有的子目录里的依赖都会组织在根目录的go.mod文件里

执行 go run server.go 运行代码会发现 go mod 会自动查找依赖自动下载
go.mod 文件

module hello

go 1.17

require (
	github.com/golang/protobuf v1.5.2 // indirect
	github.com/goplus/gop v1.0.14 // indirect
	golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 // indirect
	golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
	golang.org/x/text v0.3.7 // indirect
	google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
	google.golang.org/grpc v1.42.0 // indirect
	google.golang.org/protobuf v1.27.1 // indirect
)

我们会执行的命令

# 初始化模块
go mod init 模块名称
# 我们的示例
go mod init hello
# 运行grpc服务端
go run server.go
引用项目文件

helloworld.proto

syntax = "proto3";

package hello;

option go_package = "/protos";

// 定义一个服务
service Greeter {
  // 定义一个函数
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// 定义函数的输入
message HelloRequest {
  string name = 1;
}

// 定义函数的输出
message HelloReply {
  string message = 1;
}

在protos目录下是我们生成的grpc协议文件,了解proto 。首先我们需要编辑一个标准的proto协议文件,然后执行下面的编译命令生成go的协议文件。

protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/helloworld.proto

# 我们的示例
protoc.exe --go_out=plugins=grpc:. helloworld.proto


生成的helloworld.pb.go文件是grpc客户端和grpc服务端都需要引用的文件,用来指定一个标准的通信规则,怎么来引用这个文件呢?我们在前面初始化了我们当前项目的模块名称是 hello,所以我们在import中添加"hello/protos"来引用该文件。

grpc 客户端示例

client.go

package main

import (
    "log"
    "os"

    "golang.org/x/net/context"
    "google.golang.org/grpc"

    pb "hello/protos"
)

const (
    address     = "localhost:8888"
    defaultName = "不太灵光的程序员"
)

func main() {
    // Set up a connection to the server.
    conn, err := grpc.Dial(address, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)

    // Contact the server and print out its response.
    name := defaultName
    if len(os.Args) > 1 {
        name = os.Args[1]
    }
    r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.Message)
}
grpc 服务端示例

server.go

package main

import (
    "log"
    "net"

    "golang.org/x/net/context"
    "google.golang.org/grpc"
    "google.golang.org/grpc/reflection"

    pb "hello/protos"
)

const (
    port = ":8888"
)

// GreeterServerImplementation is used to implement helloworld.GreeterServer.
type GreeterServerImplementation struct{}

// SayHello implements helloworld.GreeterServer
func (s *GreeterServerImplementation) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &GreeterServerImplementation{})
    // Register reflection service on gRPC server.
    reflection.Register(s)
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}
运行结果
# 运行grpc服务端
go run server.go
# 运行grpc客户端
go run client.go

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/995106.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存