创建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) }
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") }
让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") }
使用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") }
客户端
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) }