grpc入门

创建gRPC服务端并运行

创建proto文件

syntax="proto3";

package services;
 

message  ProdRequest {
    int32 prod_id =1;   //传入的商品ID
}
message ProdResponse{
    int32 prod_stock=1;//商品库存
}

service ProdService {
    rpc GetProdStock (ProdRequest) returns (ProdResponse);
}

 

生成文件:

protoc --go_out=plugins=grpc:../services     Prod.proto

创建实现方法

package services

import (
    "context"
)

type ProdService struct {

}

func(this *ProdService) GetProdStock(ctx context.Context, request *ProdRequest) (*ProdResponse, error) {

      return &ProdResponse{ProdStock:20},nil
}

创建服务

package main

import (
    "google.golang.org/grpc"
    "grpcpro/services"
    "net"
)

func main()  {
    rpcServer:=grpc.NewServer()
    services.RegisterProdServiceServer(rpcServer,new(services.ProdService))

    lis,_:=net.Listen("tcp",":8081")

    rpcServer.Serve(lis)


}

go run server.go 运行服务....

创建客户端调用

我们依然 安装相关 库 安装 go get google.golang.org/grpc

自签证书、服务加入证书验证(选学)

  

进入这个网址 http://slproweb.com/products/Win32OpenSSL.html

进入 bin目录

1、执行openssl
2、执行 genrsa -des3 -out server.key 2048(会生成server.key,私钥文件)
3、创建证书请求:req -new -key server.key -out server.csr(会生成server.csr)
  其中common name 也就是域名:我填的是jtthink.com
 
4、删除密码 rsa -in server.key -out server_no_passwd.key
5、执行x509 -req -days 365 -in server.csr -signkey server_no_passwd.key -out server.crt
  (会生成server.crt)

 自此自签证书完成

加入证书代码:服务端

creds, err := credentials.NewServerTLSFromFile("keys/server.crt", "keys/server_no_passwd.key")
    if err != nil {
        log.Fatal(err)
    }
    rpcServer:=grpc.NewServer(grpc.Creds(creds))

加入证书代码:客户端

creds, err := credentials.NewClientTLSFromFile("keys/server.crt", "jtthink.com")
    if err != nil {
           log.Fatal(err)
  }
    conn,err:=grpc.Dial(":8081",grpc.WithTransportCredentials(creds))
package main

import (
    "context"
    "fmt"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "gweb.jtthink.com/services"
    "log"
)

func main(){
    creds, err := credentials.NewClientTLSFromFile("keys/server.crt", "jtthink.com")
    if err != nil {
        log.Fatal(err)
    }
    conn,err:=grpc.Dial(":8081",grpc.WithTransportCredentials(creds))
    if err!=nil{
        log.Fatal(err)
    }
    defer conn.Close()

    prodClient:=services.NewProdServiceClient(conn)
    prodRes,err:=prodClient.GetProdStock(context.Background(),
        &services.ProdRequest{ProdId:12})
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(prodRes.ProdStock)
}
main.go 客户端
package main

import (
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "gorpc.jtthink.com/services"
    "log"
    "net/http"
)

func main()  {

    creds, err := credentials.NewServerTLSFromFile("keys/server.crt", "keys/server_no_passwd.key")
    if err != nil {
        log.Fatal(err)
    }
    rpcServer:=grpc.NewServer(grpc.Creds(creds))
    services.RegisterProdServiceServer(rpcServer,new(services.ProdService))

    //lis,_:=net.Listen("tcp",":8081")
    //rpcServer.Serve(lis)

    mux:=http.NewServeMux()
    mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
        writer.Write([]byte("hello"))
    })
    httpServer:=&http.Server{
        Addr:":8081",
        Handler:mux,
    }

    httpServer.ListenAndServeTLS("keys/server.crt","keys/server_no_passwd.key")




}
server.go 服务端

让gRPC提供Http服务(初步)

package main

import (
    "fmt"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "gorpc.jtthink.com/services"
    "log"
    "net/http"
)

func main()  {

    creds, err := credentials.NewServerTLSFromFile("keys/server.crt", "keys/server_no_passwd.key")
    if err != nil {
        log.Fatal(err)
    }
    rpcServer:=grpc.NewServer(grpc.Creds(creds))
    services.RegisterProdServiceServer(rpcServer,new(services.ProdService))

    //lis,_:=net.Listen("tcp",":8081")
    //rpcServer.S

    mux:=http.NewServeMux()
    mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {

        fmt.Println(request)
        rpcServer.ServeHTTP(writer,request)
    })
    httpServer:=&http.Server{
        Addr:":8081",
        Handler:mux,
    }
    httpServer.ListenAndServeTLS("keys/server.crt","keys/server_no_passwd.key")





}
server.go

使用CA证书

根证书(root certificate)是属于根证书颁发机构(CA)的公钥证书。 用以验证它所签发的证书(客户端、服务端)
1、openssl
2、 genrsa -out ca.key 2048
3、req -new -x509 -days 3650 -key ca.key -out ca.pem

重新生成服务端证书

1、 genrsa -out server.key 2048
2、req -new -key server.key -out server.csr
  注意common name 请填写localhost

3、x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in server.csr -out server.pem

生成客户端

1、 ecparam -genkey -name secp384r1 -out client.key
2、 req -new -key client.key -out client.csr

3、x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in client.csr -out client.pem

程序中重新覆盖server.crt和server.key

服务端代码改造

cert,_:=tls.LoadX509KeyPair("cert/server.pem","cert/server.key")
    certPool := x509.NewCertPool()
    ca, _ := ioutil.ReadFile("cert/ca.pem")
    certPool.AppendCertsFromPEM(ca)

    creds:=credentials.NewTLS(&tls.Config{
        Certificates: []tls.Certificate{cert},
        ClientAuth:   tls.RequireAndVerifyClientCert,
        ClientCAs:    certPool,
    })

客户端代码改造

cert,_:=tls.LoadX509KeyPair("cert/client.pem","cert/client.key")
    certPool := x509.NewCertPool()
    ca, _ := ioutil.ReadFile("cert/ca.pem")
    certPool.AppendCertsFromPEM(ca)

    creds:=credentials.NewTLS(&tls.Config{
        Certificates: []tls.Certificate{cert},
        ServerName: "localhost",
        RootCAs:      certPool,
    })

服务端:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "gorpc.jtthink.com/services"
    "io/ioutil"
    "net"
)

func main()  {

    //creds, err := credentials.NewServerTLSFromFile("keys/server.crt",
    //    "keys/server.key")
    //if err != nil {
    //    log.Fatal(err)
    //}
    cert,_:=tls.LoadX509KeyPair("cert/server.pem","cert/server.key")
    certPool := x509.NewCertPool()
    ca, _ := ioutil.ReadFile("cert/ca.pem")
    certPool.AppendCertsFromPEM(ca)

    creds:=credentials.NewTLS(&tls.Config{
        Certificates: []tls.Certificate{cert},//服务端证书
        ClientAuth:   tls.RequireAndVerifyClientCert,
        ClientCAs:    certPool,
    })


     rpcServer:=grpc.NewServer(grpc.Creds(creds))
    services.RegisterProdServiceServer(rpcServer,new(services.ProdService))

    lis,_:=net.Listen("tcp",":8081")
    rpcServer.Serve(lis)

    //mux:=http.NewServeMux()
    //mux.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
    //     rpcServer.ServeHTTP(writer,request)
    //})
    //httpServer:=&http.Server{
    //    Addr:":8081",
    //    Handler:mux,
    //}
    //httpServer.ListenAndServeTLS("keys/server.crt","keys/server.key")


}
server.go

客户端

package main

import (
    "context"
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "gweb.jtthink.com/services"
    "io/ioutil"
    "log"
)

func main(){
    //creds, err := credentials.NewClientTLSFromFile("keys/server.crt", "localhost")
    //if err != nil {
    //    log.Fatal(err)
    //}

    cert,_:=tls.LoadX509KeyPair("cert/client.pem","cert/client.key")
    certPool := x509.NewCertPool()
    ca, _ := ioutil.ReadFile("cert/ca.pem")
    certPool.AppendCertsFromPEM(ca)

    creds:=credentials.NewTLS(&tls.Config{
        Certificates: []tls.Certificate{cert},//客户端证书
        ServerName: "localhost",
        RootCAs:      certPool,
    })


    conn,err:=grpc.Dial(":8081",grpc.WithTransportCredentials(creds))
    if err!=nil{
        log.Fatal(err)
    }
    defer conn.Close()

    prodClient:=services.NewProdServiceClient(conn)
    prodRes,err:=prodClient.GetProdStock(context.Background(),
        &services.ProdRequest{ProdId:12})
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(prodRes.ProdStock)
}
View Code
原文地址:https://www.cnblogs.com/sunlong88/p/11845622.html