Server

Example: 102basic

你可以在服务端实现Service。

Service的类型并不重要。你可以使用自定义类型来保持状态,或者直接使用 struct{}int

你需要启动一个TCP或UDP服务器来暴露Service。

你也可以添加一些plugin来为服务器增加新特性。

Service

作为服务提供者,首先你需要定义服务。 当前rpcx仅支持 可导出的 methods (方法) 作为服务的函数。 (see 可导出) 并且这个可导出的方法必须满足以下的要求:

  • 必须是可导出类型的方法
  • 接受3个参数,第一个是 context.Context类型,其他2个都是可导出(或内置)的类型。
  • 第3个参数是一个指针
  • 有一个 error 类型的返回值

你可以使用 RegisterName 来注册 rcvr 的方法,这里这个服务的名字叫做 name。 如果你使用 Register, 生成的服务的名字就是 rcvr的类型名。 你可以在注册中心添加一些元数据供客户端或者服务管理者使用。例如 weightgeolocationmetrics

  1. func (s *Server) Register(rcvr interface{}, metadata string) error
  2. func (s *Server) RegisterName(name string, rcvr interface{}, metadata string) error

这里是一个实现了 Mul 方法的例子:

  1. import "context"
  2. type Args struct {
  3. A int
  4. B int
  5. }
  6. type Reply struct {
  7. C int
  8. }
  9. type Arith int
  10. func (t *Arith) Mul(ctx context.Context, args *Args, reply *Reply) error {
  11. reply.C = args.A * args.B
  12. return nil
  13. }

在这个例子中,你可以定义 Arithstruct{} 类型, 它不会影响到这个服务。 你也可以定义 argsArgs, 也不会产生影响。

Server

在你定义完服务后,你会想将它暴露出去来使用。你应该通过启动一个TCP或UDP服务器来监听请求。

服务器支持以如下这些方式启动,监听请求和关闭:

  1. func NewServer(options ...OptionFn) *Server
  2. func (s *Server) Close() error
  3. func (s *Server) RegisterOnShutdown(f func())
  4. func (s *Server) Serve(network, address string) (err error)
  5. func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)

首先你应使用 NewServer 来创建一个服务器实例。其次你可以调用 Serve 或者 ServeHTTP 来监听请求。

服务器包含一些字段(有一些是不可导出的):

  1. type Server struct {
  2. Plugins PluginContainer
  3. // AuthFunc 可以用来鉴权
  4. AuthFunc func(ctx context.Context, req *protocol.Message, token string) error
  5. // 包含过滤后或者不可导出的字段
  6. }

Plugins 包含了服务器上所有的插件。我们会在之后的章节介绍它。

AuthFunc 是一个可以检查客户端是否被授权了的鉴权函数。我们也会在之后的章节介绍它。

rpcx 提供了 3个 OptionFn 来设置启动选项:

  1. func WithReadTimeout(readTimeout time.Duration) OptionFn
  2. func WithTLSConfig(cfg *tls.Config) OptionFn
  3. func WithWriteTimeout(writeTimeout time.Duration) OptionFn

可以设置 读超时、写超时和tls证书。

ServeHTTP 将服务通过HTTP暴露出去。

Serve 通过TCP或UDP协议与客户端通信。

rpcx 支持如下的网络类型:

  • tcp: 推荐使用
  • http: 通过劫持http连接实现
  • unix: unix domain sockets
  • reuseport: 要求 SO_REUSEPORT socket 选项, 仅支持 Linux kernel 3.9+
  • quic: support quic protocol
  • kcp: sopport kcp protocol

下面是一个服务器的示例代码:

  1. package main
  2. import (
  3. "flag"
  4. example "github.com/rpcx-ecosystem/rpcx-examples3"
  5. "github.com/smallnest/rpcx/server"
  6. )
  7. var (
  8. addr = flag.String("addr", "localhost:8972", "server address")
  9. )
  10. func main() {
  11. flag.Parse()
  12. s := server.NewServer()
  13. //s.RegisterName("Arith", new(example.Arith), "")
  14. s.Register(new(example.Arith), "")
  15. s.Serve("tcp", *addr)
  16. }