zoukankan      html  css  js  c++  java
  • go-micro server 服务器

      go-micro 支持很多通信协议:http、tcp、grpc等,支持的编码方式也很多有json、protobuf、bytes、jsonrpc等。也可以根据自己的需要实现通信协议和编码方式。go-micro 默认的通信协议是http,默认的编码方式是protobuf。

      主要代码定义如下:

    type Server interface {
    	Options() Options
    	Init(...Option) error
    	Handle(Handler) error
    	NewHandler(interface{}, ...HandlerOption) Handler
    	NewSubscriber(string, interface{}, ...SubscriberOption) Subscriber
    	Subscribe(Subscriber) error
    	Register() error
    	Deregister() error
    	Start() error
    	Stop() error
    	String() string
    }
    
    type Message interface {
    	Topic() string
    	Payload() interface{}
    	ContentType() string
    }
    
    type Request interface {
    	Service() string
    	Method() string
    	ContentType() string
    	Request() interface{}
    	// indicates whether the request will be streamed
    	Stream() bool
    }
    
    // Stream represents a stream established with a client.
    // A stream can be bidirectional which is indicated by the request.
    // The last error will be left in Error().
    // EOF indicated end of the stream.
    type Stream interface {
    	Context() context.Context
    	Request() Request
    	Send(interface{}) error
    	Recv(interface{}) error
    	Error() error
    	Close() error
    }
    
    type Option func(*Options)
    
    type HandlerOption func(*HandlerOptions)
    
    type SubscriberOption func(*SubscriberOptions)
    

      

      server 启动时会注册 handler ,即方法路由。注册机制是利用反射,把对象的信息完全提取出来,解析出结构体内的方法及方法的参数,保存到一个map内: map[结构体名称][方法信息集合]

    func (s *rpcServer) Handle(h Handler) error {
    	s.Lock()
    	defer s.Unlock()
    
    	if err := s.rpc.register(h.Handler()); err != nil {
    		return err
    	}
    
    	s.handlers[h.Name()] = h
    
    	return nil
    }
    

      

    func (server *server) register(rcvr interface{}) error {
    	server.mu.Lock()
    	defer server.mu.Unlock()
    	if server.serviceMap == nil {
    		server.serviceMap = make(map[string]*service)
    	}
    	s := new(service)
    	s.typ = reflect.TypeOf(rcvr)
    	s.rcvr = reflect.ValueOf(rcvr)
    	sname := reflect.Indirect(s.rcvr).Type().Name()
    	if sname == "" {
    		log.Fatal("rpc: no service name for type", s.typ.String())
    	}
    	if !isExported(sname) {
    		s := "rpc Register: type " + sname + " is not exported"
    		log.Log(s)
    		return errors.New(s)
    	}
    	if _, present := server.serviceMap[sname]; present {
    		return errors.New("rpc: service already defined: " + sname)
    	}
    	s.name = sname
    	s.method = make(map[string]*methodType)
    
    	// Install the methods
    	for m := 0; m < s.typ.NumMethod(); m++ {
    		method := s.typ.Method(m)
    		if mt := prepareMethod(method); mt != nil {
    			s.method[method.Name] = mt
    		}
    	}
    
    	if len(s.method) == 0 {
    		s := "rpc Register: type " + sname + " has no exported methods of suitable type"
    		log.Log(s)
    		return errors.New(s)
    	}
    	server.serviceMap[s.name] = s
    	return nil
    }
    

      

    type methodType struct {
    	sync.Mutex  // protects counters
    	method      reflect.Method
    	ArgType     reflect.Type
    	ReplyType   reflect.Type
    	ContextType reflect.Type
    	stream      bool
    }
    
    type service struct {
    	name   string                 // name of service
    	rcvr   reflect.Value          // receiver of methods for the service
    	typ    reflect.Type           // type of the receiver
    	method map[string]*methodType // registered methods
    }
    

      

      路由信息处理完后,主要的工作就已经完成了,然后注册服务并启动服务,启动的服务是一个http的服务。启动流程如下:

    you are the best!
  • 相关阅读:
    最容易被淘汰的八种人
    java基础编程——用两个栈来实现一个队列
    java基础编程——重建二叉树
    java基础——多线程
    java基础编程——链表反转
    java基础——线程池
    java基础——线程
    java基础编程——二维数组中的查找
    网络编程——TCP协议和通信
    网络编程——UDP协议和通信
  • 原文地址:https://www.cnblogs.com/linguoguo/p/14710327.html
Copyright © 2011-2022 走看看