服务器
例程:102basic
你可以在服务器端实现服务。
服务的类型不重要。你可以使用自定义的类型来保存状态,或者简单的使用struct{}
或者int
。
你应该启动一个TCP或者UDP服务器来提供服务。
你也可以设置一些插件来给服务器添加特性。
服务
作为服务提供者,你首先需要定义一些服务。当前rpcx只支持导出的方法作为服务的函数。导出的方法必须满足以下规则:
- 导出类型的导出方法
- 三个参数,第一个是context.Context,两个导出类型
- 第三个参数是一个指针
- 一个返回值,返回error类型
rpcx 3.1中我们想加入注册满足以上三个条件的原始的函数来作为服务,但是在rpx 3.0中,你必须使用method来实现服务。
你可以使用RegisterName来注册,方法作为rcvr参数,服务的名字作为name参数。如果你使用Register,生成的服务的名字是rcvr的类型名字。你可以在注册时添加服务的元数据,可以用于客户端或者服务管理器,例如:
weight
、geolocation
、metrics
。
func (s *Server) Register(rcvr interface{}, metadata string) error
func (s *Server) RegisterName(name string, rcvr interface{}, metadata string) error
这里有一个实现了Mul
方法的例程:
import "context"
type Args struct {
A int
B int
}
type Reply struct {
C int
}
type Arith intfunc (t *Arith) Mul(ctx context.Context, args *Args, reply *Reply) error {
reply.C = args.A * args.B
return nil
}
服务器
定义服务之后,你应该希望暴露给用户。你应该启动一个TCP服务器或者UDP服务器来监听。
服务器支持以下的方式来启动、监听以及关闭:
func NewServer(options ...OptionFn) *Server
func (s *Server) Close() error
func (s *Server) RegisterOnShutdown(f func())
func (s *Server) Serve(network, address string) (err error)
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)
首先你使用NewServer
使用选项来创建一个服务器实例。第二,你可以调用Serve
或者ServeHTTP
来提供服务。
服务器包含一些域(和一些未导出的域):
type Server struct {
Plugins PluginContainer
// AuthFunc can be used to auth.
AuthFunc func(ctx context.Context, req *protocol.Message, token string) error
// contains filtered or unexported fields
}
plugins
包含服务器里的所有插件。我们会在之后的章节里介绍。
AuthFunc
是一个授权函数,可以用来检查客户端是否被授权。它也会之后介绍。
rpcx
提供三个OptionFn
来设置参数:
func WithReadTimeout(readTimeout time.Duration) OptionFn
func WithTLSConfig(cfg *tls.Config) OptionFn
func WithWriteTimeout(writeTimeout time.Duration) OptionFn
这些可以设置readTimeout、writeTimeout和tls.Config。
ServeHttp
使用一个HTTP连接来提供服务。它通过劫持连接来与客户端通讯。
Serve
使用TCP或者UDP协议来与客户端通讯。
rpcx支持以下的网络:
- tcp:推荐的网络
- http:劫持http连接
- unix:unix域套接字
- reuseport:使用SO_REUSEPORT套接字选项,只支持Linux内核3.9+
- quic:支持quic协议
- kcp:支持kcp协议
这里有一个服务器示例:
package main
import (
"flag"
example "github.com/rpcx-ecosystem/rpcx-examples3"
"github.com/smallnest/rpcx/server"
)
var (
addr = flag.String("addr", "localhost:8972", "server address")
)
func main() {
flag.Parse()
s := server.NewServer()
//s.RegisterName("Arith", new(example.Arith), "")
s.Register(new(example.Arith), "")
s.Serve("tcp", *addr)
}