Skip to content

Commit

Permalink
feat: Add grpc client & server
Browse files Browse the repository at this point in the history
- Add grpc client and server
#16
  • Loading branch information
lc-1010 committed Jul 10, 2023
1 parent 0636124 commit a884cc9
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 5 deletions.
24 changes: 24 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"context"
"log"

pb "github.com/lc-1010/OneBlogService/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

func main() {
ctx := context.Background()
clientConn, _ := GetClientConn(ctx, "localhost:8004", nil)
defer clientConn.Close()
tagServiceClient := pb.NewTagServiceClient(clientConn)
resp, _ := tagServiceClient.GetTagList(ctx, &pb.GetTagListRequst{Name: "rust"})
log.Printf("resp:%v", resp)
}

func GetClientConn(ctx context.Context, target string, opts []grpc.DialOption) (*grpc.ClientConn, error) {
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
return grpc.DialContext(ctx, target, opts...)
}
66 changes: 66 additions & 0 deletions cmd/multiple/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"flag"
"log"
"net"
"net/http"

pb "github.com/lc-1010/OneBlogService/proto"
"github.com/lc-1010/OneBlogService/server"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)

var grpcPort string
var httpPort string

func init() {
flag.StringVar(&grpcPort, "grpc_port", "8001", "grpc启动端口")
flag.StringVar(&httpPort, "http_port", "8002", "http启动端口")
flag.Parse()
}

func RunHttpServer(port string) error {
serveMux := http.NewServeMux() //多路复用

serveMux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(`pong`))
})
return http.ListenAndServe(":"+port, serveMux)
}

func RunGrpcServer(port string) error {
s := grpc.NewServer()
pb.RegisterTagServiceServer(s, server.NewTagServer())
reflection.Register(s)
lis, err := net.Listen("tcp", ":"+port)
if err != nil {
return err
}
return s.Serve(lis)
}

// grpcurl -plaintext localhost:8001 proto.TagService.GetTagList
// curl 127.0.0.1:8002/ping
func main() {

errs := make(chan error)
go func() {
err := RunHttpServer(httpPort)
if err != nil {
errs <- err
}
}()
go func() {
err := RunGrpcServer(grpcPort)
if err != nil {
errs <- err
}
}()

err := <-errs
if err != nil {
log.Fatalf("Run Server err:%v", err)
}
}
30 changes: 30 additions & 0 deletions cmd/rpc/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"log"
"net"

pb "github.com/lc-1010/OneBlogService/proto"
"github.com/lc-1010/OneBlogService/server"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)

var port string

func main() {
port = "8004"
s := grpc.NewServer()
tag := server.NewTagServer()
pb.RegisterTagServiceServer(s, tag)
reflection.Register(s)
lis, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Fatalf("net.Listen err:%v", err)

}
err = s.Serve(lis)
if err != nil {
log.Fatalf("serve err:%v", err)
}
}
69 changes: 69 additions & 0 deletions pkg/blog_api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package blog_api

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)

const (
APP_KEY = "APP_KEY"
APP_SECRET = "APP_SECRET"
)

// API blog api sdk
type API struct {
URL string
Client *http.Client
}

// AccessToken
type AccessToken struct {
Token string `json:"token"`
}

// NewAPI creates a new API instance.
//
// It takes a URL string as a parameter and returns a pointer to an API object.
func NewAPI(url string) *API {
return &API{URL: url, Client: http.DefaultClient}
}

func (a *API) getAccessToken(c context.Context) (string, error) {

body, err := a.httpGet(c, fmt.Sprintf("%s?app_key=%s&app_secret=%s", "auth", APP_KEY, APP_SECRET))
if err != nil {
return "", err
}
var accessToken AccessToken
_ = json.Unmarshal(body, &accessToken)
return accessToken.Token, nil
}

// httpGet get function
func (a *API) httpGet(ctx context.Context, path string) ([]byte, error) {
resp, err := http.Get(fmt.Sprintf("%s/%s", a.URL, path))
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
return body, nil
}

func (a *API) GetTagList(ctx context.Context, name string) ([]byte, error) {
token, err := a.getAccessToken(ctx)
if err != nil {
log.Println(err)
return nil, err
}

body, err := a.httpGet(ctx, fmt.Sprintf("%s?token=%s&name=%s", "api/v1/tags", token, name))
if err != nil {
return nil, err
}
return body, nil
}
10 changes: 5 additions & 5 deletions pkg/errcode/common_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type Error struct {
details []string
}

var codes = map[int]string{}
var b_codes = map[int]string{}

// NewError creates a new Error object with the given code and message.
//
Expand All @@ -23,10 +23,10 @@ var codes = map[int]string{}
// Returns:
// - *Error: a pointer to the newly created Error object.
func NewError(code int, msg string) *Error {
if _, ok := codes[code]; ok {
if _, ok := b_codes[code]; ok {
panic(fmt.Sprintf("This code %d already exists. Please try another one", code))
}
codes[code] = msg
b_codes[code] = msg
return &Error{
code: code,
msg: msg,
Expand Down Expand Up @@ -59,8 +59,8 @@ var (
UnauthoerizedTokenGenerate = NewError(1000006, "Unauthorized Token Generate")

// TooManyRequests 表示请求过多
TooManyRequests = NewError(1000007, "Too Many Requests")

TooManyRequests = NewError(1000007, "Too Many Requests")
MethodNotAllowed = NewError(10000008, "不支持该方法")
//ServerError = NewError(1000000, "server error")
)

Expand Down
57 changes: 57 additions & 0 deletions pkg/errcode/rpc_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package errcode

import (
pb "github.com/lc-1010/OneBlogService/proto"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

func TogRPCError(err *Error) error {
s, _ := status.New(ToRPCCode(err.Code()), err.Msg()).
WithDetails(&pb.Error{
Code: int32(err.Code()),
Message: err.Msg()})
return s.Err()
}

func ToRPCCode(code int) codes.Code {
var statusCode codes.Code

switch code {
case ServerError.Code():
statusCode = codes.Internal
case InvalidParams.Code():
statusCode = codes.InvalidArgument
case UnauthoerizedTokenError.Code():
statusCode = codes.Unauthenticated
case UnauthoerizedTokenTimeout.Code():
statusCode = codes.DeadlineExceeded
case NotFound.Code():
statusCode = codes.NotFound
case TooManyRequests.Code():
statusCode = codes.ResourceExhausted
case MethodNotAllowed.Code():
statusCode = codes.Unimplemented
default:
statusCode = codes.Unknown

}
return statusCode
}

type Status struct {
*status.Status
}

func ToRPCStatus(code int, msg string) *Status {
s, _ := status.New(ToRPCCode((code)), msg).
WithDetails(&pb.Error{Code: int32(code),
Message: msg})
return &Status{s}
}

func FromError(err error) *Status {
s, _ := status.FromError(err)
return &Status{s}
}
40 changes: 40 additions & 0 deletions server/tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package server

import (
"context"
"encoding/json"

"github.com/lc-1010/OneBlogService/pkg/blog_api"
"github.com/lc-1010/OneBlogService/pkg/errcode"
pb "github.com/lc-1010/OneBlogService/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

type TagService struct {
pb.UnimplementedTagServiceServer
}

func NewTagServer() *TagService {
return &TagService{}
}

// GetTagList(context.Context, *GetTagListRequst) (*GetTagListReply, error)
func (t *TagService) GetTagList(c context.Context, r *pb.GetTagListRequst) (*pb.GetTagListReply, error) {
api := blog_api.NewAPI("http://127.0.0.1:8000")
body, err := api.GetTagList(c, r.GetName())
if err != nil {
return nil, errcode.TogRPCError(errcode.ErrorGetTagListFail)
}
tagList := pb.GetTagListReply{}
err = json.Unmarshal(body, &tagList)
if err != nil {
return nil, errcode.TogRPCError(errcode.ServerError)
}
return &tagList, nil
}

func GetClientConn(ctx context.Context, target string, opts []grpc.DialOption) (*grpc.ClientConn, error) {
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
return grpc.DialContext(ctx, target, opts...)
}

0 comments on commit a884cc9

Please sign in to comment.