github.com/annwntech/go-micro/v2@v2.9.5/server/server.go (about)

     1  // Package server is an interface for a micro server
     2  package server
     3  
     4  import (
     5  	"context"
     6  	"os"
     7  	"os/signal"
     8  	"time"
     9  
    10  	"github.com/google/uuid"
    11  	"github.com/annwntech/go-micro/v2/codec"
    12  	"github.com/annwntech/go-micro/v2/logger"
    13  	"github.com/annwntech/go-micro/v2/registry"
    14  	signalutil "github.com/annwntech/go-micro/v2/util/signal"
    15  )
    16  
    17  // Server is a simple micro server abstraction
    18  type Server interface {
    19  	// Initialise options
    20  	Init(...Option) error
    21  	// Retrieve the options
    22  	Options() Options
    23  	// Register a handler
    24  	Handle(Handler) error
    25  	// Create a new handler
    26  	NewHandler(interface{}, ...HandlerOption) Handler
    27  	// Create a new subscriber
    28  	NewSubscriber(string, interface{}, ...SubscriberOption) Subscriber
    29  	// Register a subscriber
    30  	Subscribe(Subscriber) error
    31  	// Start the server
    32  	Start() error
    33  	// Stop the server
    34  	Stop() error
    35  	// Server implementation
    36  	String() string
    37  }
    38  
    39  // Router handle serving messages
    40  type Router interface {
    41  	// ProcessMessage processes a message
    42  	ProcessMessage(context.Context, Message) error
    43  	// ServeRequest processes a request to completion
    44  	ServeRequest(context.Context, Request, Response) error
    45  }
    46  
    47  // Message is an async message interface
    48  type Message interface {
    49  	// Topic of the message
    50  	Topic() string
    51  	// The decoded payload value
    52  	Payload() interface{}
    53  	// The content type of the payload
    54  	ContentType() string
    55  	// The raw headers of the message
    56  	Header() map[string]string
    57  	// The raw body of the message
    58  	Body() []byte
    59  	// Codec used to decode the message
    60  	Codec() codec.Reader
    61  }
    62  
    63  // Request is a synchronous request interface
    64  type Request interface {
    65  	// Service name requested
    66  	Service() string
    67  	// The action requested
    68  	Method() string
    69  	// Endpoint name requested
    70  	Endpoint() string
    71  	// Content type provided
    72  	ContentType() string
    73  	// Header of the request
    74  	Header() map[string]string
    75  	// Body is the initial decoded value
    76  	Body() interface{}
    77  	// Read the undecoded request body
    78  	Read() ([]byte, error)
    79  	// The encoded message stream
    80  	Codec() codec.Reader
    81  	// Indicates whether its a stream
    82  	Stream() bool
    83  }
    84  
    85  // Response is the response writer for unencoded messages
    86  type Response interface {
    87  	// Encoded writer
    88  	Codec() codec.Writer
    89  	// Write the header
    90  	WriteHeader(map[string]string)
    91  	// write a response directly to the client
    92  	Write([]byte) error
    93  }
    94  
    95  // Stream represents a stream established with a client.
    96  // A stream can be bidirectional which is indicated by the request.
    97  // The last error will be left in Error().
    98  // EOF indicates end of the stream.
    99  type Stream interface {
   100  	Context() context.Context
   101  	Request() Request
   102  	Send(interface{}) error
   103  	Recv(interface{}) error
   104  	Error() error
   105  	Close() error
   106  }
   107  
   108  // Handler interface represents a request handler. It's generated
   109  // by passing any type of public concrete object with endpoints into server.NewHandler.
   110  // Most will pass in a struct.
   111  //
   112  // Example:
   113  //
   114  //      type Greeter struct {}
   115  //
   116  //      func (g *Greeter) Hello(context, request, response) error {
   117  //              return nil
   118  //      }
   119  //
   120  type Handler interface {
   121  	Name() string
   122  	Handler() interface{}
   123  	Endpoints() []*registry.Endpoint
   124  	Options() HandlerOptions
   125  }
   126  
   127  // Subscriber interface represents a subscription to a given topic using
   128  // a specific subscriber function or object with endpoints. It mirrors
   129  // the handler in its behaviour.
   130  type Subscriber interface {
   131  	Topic() string
   132  	Subscriber() interface{}
   133  	Endpoints() []*registry.Endpoint
   134  	Options() SubscriberOptions
   135  }
   136  
   137  type Option func(*Options)
   138  
   139  var (
   140  	DefaultAddress                 = ":0"
   141  	DefaultName                    = "go.micro.server"
   142  	DefaultVersion                 = "latest"
   143  	DefaultId                      = uuid.New().String()
   144  	DefaultServer           Server = newRpcServer()
   145  	DefaultRouter                  = newRpcRouter()
   146  	DefaultRegisterCheck           = func(context.Context) error { return nil }
   147  	DefaultRegisterInterval        = time.Second * 30
   148  	DefaultRegisterTTL             = time.Second * 90
   149  
   150  	// NewServer creates a new server
   151  	NewServer func(...Option) Server = newRpcServer
   152  	log                              = logger.NewHelper(logger.DefaultLogger).WithFields(map[string]interface{}{"service": "server"})
   153  )
   154  
   155  // DefaultOptions returns config options for the default service
   156  func DefaultOptions() Options {
   157  	return DefaultServer.Options()
   158  }
   159  
   160  // Init initialises the default server with options passed in
   161  func Init(opt ...Option) {
   162  	if DefaultServer == nil {
   163  		DefaultServer = newRpcServer(opt...)
   164  	}
   165  	DefaultServer.Init(opt...)
   166  }
   167  
   168  // NewRouter returns a new router
   169  func NewRouter() *router {
   170  	return newRpcRouter()
   171  }
   172  
   173  // NewSubscriber creates a new subscriber interface with the given topic
   174  // and handler using the default server
   175  func NewSubscriber(topic string, h interface{}, opts ...SubscriberOption) Subscriber {
   176  	return DefaultServer.NewSubscriber(topic, h, opts...)
   177  }
   178  
   179  // NewHandler creates a new handler interface using the default server
   180  // Handlers are required to be a public object with public
   181  // endpoints. Call to a service endpoint such as Foo.Bar expects
   182  // the type:
   183  //
   184  //	type Foo struct {}
   185  //	func (f *Foo) Bar(ctx, req, rsp) error {
   186  //		return nil
   187  //	}
   188  //
   189  func NewHandler(h interface{}, opts ...HandlerOption) Handler {
   190  	return DefaultServer.NewHandler(h, opts...)
   191  }
   192  
   193  // Handle registers a handler interface with the default server to
   194  // handle inbound requests
   195  func Handle(h Handler) error {
   196  	return DefaultServer.Handle(h)
   197  }
   198  
   199  // Subscribe registers a subscriber interface with the default server
   200  // which subscribes to specified topic with the broker
   201  func Subscribe(s Subscriber) error {
   202  	return DefaultServer.Subscribe(s)
   203  }
   204  
   205  // Run starts the default server and waits for a kill
   206  // signal before exiting. Also registers/deregisters the server
   207  func Run() error {
   208  	if err := Start(); err != nil {
   209  		return err
   210  	}
   211  
   212  	ch := make(chan os.Signal, 1)
   213  	signal.Notify(ch, signalutil.Shutdown()...)
   214  
   215  	if logger.V(logger.InfoLevel, log) {
   216  		log.Infof("Received signal %s", <-ch)
   217  	}
   218  	return Stop()
   219  }
   220  
   221  // Start starts the default server
   222  func Start() error {
   223  	config := DefaultServer.Options()
   224  	if logger.V(logger.InfoLevel, log) {
   225  		log.Infof("Starting server %s id %s", config.Name, config.Id)
   226  	}
   227  	return DefaultServer.Start()
   228  }
   229  
   230  // Stop stops the default server
   231  func Stop() error {
   232  	if logger.V(logger.InfoLevel, log) {
   233  		log.Infof("Stopping server")
   234  	}
   235  	return DefaultServer.Stop()
   236  }
   237  
   238  // String returns name of Server implementation
   239  func String() string {
   240  	return DefaultServer.String()
   241  }