服务器

例程102basic

你可以在服务器端实现服务。

服务的类型不重要。你可以使用自定义的类型来保存状态,或者简单的使用struct{}或者int

你应该启动一个TCP或者UDP服务器来提供服务。

你也可以设置一些插件来给服务器添加特性。

服务

作为服务提供者,你首先需要定义一些服务。当前rpcx只支持导出的方法作为服务的函数。导出的方法必须满足以下规则:

  • 导出类型的导出方法
  • 三个参数,第一个是context.Context,两个导出类型
  • 第三个参数是一个指针
  • 一个返回值,返回error类型

rpcx 3.1中我们想加入注册满足以上三个条件的原始的函数来作为服务,但是在rpx 3.0中,你必须使用method来实现服务。

你可以使用RegisterName来注册,方法作为rcvr参数,服务的名字作为name参数。如果你使用Register,生成的服务的名字是rcvr的类型名字。你可以在注册时添加服务的元数据,可以用于客户端或者服务管理器,例如:

weightgeolocationmetrics

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)
}

results matching ""

    No results matching ""