github.com/goravel/framework@v1.13.9/grpc/application.go (about)

     1  package grpc
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  	"strings"
     9  
    10  	"github.com/gookit/color"
    11  	grpcmiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
    12  	"google.golang.org/grpc"
    13  	"google.golang.org/grpc/credentials/insecure"
    14  
    15  	"github.com/goravel/framework/contracts/config"
    16  )
    17  
    18  type Application struct {
    19  	config                       config.Config
    20  	server                       *grpc.Server
    21  	unaryClientInterceptorGroups map[string][]grpc.UnaryClientInterceptor
    22  }
    23  
    24  func NewApplication(config config.Config) *Application {
    25  	return &Application{
    26  		config: config,
    27  	}
    28  }
    29  
    30  func (app *Application) Server() *grpc.Server {
    31  	return app.server
    32  }
    33  
    34  func (app *Application) Client(ctx context.Context, name string) (*grpc.ClientConn, error) {
    35  	host := app.config.GetString(fmt.Sprintf("grpc.clients.%s.host", name))
    36  	if host == "" {
    37  		return nil, errors.New("client host can't be empty")
    38  	}
    39  	if !strings.Contains(host, ":") {
    40  		port := app.config.GetString(fmt.Sprintf("grpc.clients.%s.port", name))
    41  		if port == "" {
    42  			return nil, errors.New("client port can't be empty")
    43  		}
    44  
    45  		host += ":" + port
    46  	}
    47  
    48  	interceptors, ok := app.config.Get(fmt.Sprintf("grpc.clients.%s.interceptors", name)).([]string)
    49  	if !ok {
    50  		return nil, fmt.Errorf("the type of clients.%s.interceptors must be []string", name)
    51  	}
    52  
    53  	clientInterceptors := app.getClientInterceptors(interceptors)
    54  
    55  	return grpc.DialContext(
    56  		ctx,
    57  		host,
    58  		grpc.WithTransportCredentials(insecure.NewCredentials()),
    59  		grpc.WithChainUnaryInterceptor(clientInterceptors...),
    60  	)
    61  }
    62  
    63  func (app *Application) Run(host ...string) error {
    64  	if len(host) == 0 {
    65  		defaultHost := app.config.GetString("grpc.host")
    66  		if defaultHost == "" {
    67  			return errors.New("host can't be empty")
    68  		}
    69  
    70  		if !strings.Contains(defaultHost, ":") {
    71  			defaultPort := app.config.GetString("grpc.port")
    72  			if defaultPort == "" {
    73  				return errors.New("port can't be empty")
    74  			}
    75  			defaultHost += ":" + defaultPort
    76  		}
    77  
    78  		host = append(host, defaultHost)
    79  	}
    80  
    81  	listen, err := net.Listen("tcp", host[0])
    82  	if err != nil {
    83  		return err
    84  	}
    85  	color.Greenln("[GRPC] Listening and serving gRPC on " + host[0])
    86  	if err := app.server.Serve(listen); err != nil {
    87  		return err
    88  	}
    89  
    90  	return nil
    91  }
    92  
    93  func (app *Application) UnaryServerInterceptors(unaryServerInterceptors []grpc.UnaryServerInterceptor) {
    94  	app.server = grpc.NewServer(grpc.UnaryInterceptor(
    95  		grpcmiddleware.ChainUnaryServer(unaryServerInterceptors...),
    96  	))
    97  }
    98  
    99  func (app *Application) UnaryClientInterceptorGroups(unaryClientInterceptorGroups map[string][]grpc.UnaryClientInterceptor) {
   100  	app.unaryClientInterceptorGroups = unaryClientInterceptorGroups
   101  }
   102  
   103  func (app *Application) getClientInterceptors(interceptors []string) []grpc.UnaryClientInterceptor {
   104  	var unaryClientInterceptors []grpc.UnaryClientInterceptor
   105  	for _, interceptor := range interceptors {
   106  		for client, clientInterceptors := range app.unaryClientInterceptorGroups {
   107  			if interceptor == client {
   108  				unaryClientInterceptors = append(unaryClientInterceptors, clientInterceptors...)
   109  			}
   110  		}
   111  	}
   112  
   113  	return unaryClientInterceptors
   114  }