README

jsonrpc Build Status codecov license

JSON RPC 2.0 的实现,目前实现了对以下传输层的接口:

  • socket, net 包中所有支持 Conn 接口的实现;
  • websocket, 采用了 github.com/gorilla/websocket 作为底层调用;
  • HTTP 普通的 HTTP 请求方式;

目前不支持批处理模式!

Socket

srv := NewServer()
listen, err := net.Listen("tcp", ":8080")
for {
    c, err := listen.Accept()
    conn := srv.NewConn(NewSocketTransport(true, c), nil)
    conn.Serve(ctx)

    // 主动请求客户端
    conn.Send("/method", in, func(result *result) error {
        // 此处用于处理返回的数据
    })
}

HTTP

srv := NewServer()
conn := srv.NewHTTPConn(nil)
http.Handle(conn)

安装

go get github.com/issue9/jsonrpc

文档

Go Walker PkgGoDev

版权

本项目采用 MIT 开源授权许可证,完整的授权说明可在 LICENSE 文件中找到。

Expand ▾ Collapse ▴

Documentation

Overview

    Package jsonrpc 实现简单的 JSON RPC 2.0

    https://wiki.geekdream.com/Specification/json-rpc_2.0.html

    Index

    Constants

    View Source
    const (
    	CodeParseError     = -32700
    	CodeInvalidRequest = -32600
    	CodeMethodNotFound = -32601
    	CodeInvalidParams  = -32602
    	CodeInternalError  = -32603
    )

      JSON RPC 2.0 定义的错误代码

      View Source
      const Version = "2.0"

        Version JSON RPC 的版本

        Variables

        This section is empty.

        Functions

        This section is empty.

        Types

        type Conn

        type Conn struct {
        	// contains filtered or unexported fields
        }

          Conn JSON RPC 连接对象

          json-rpc 客户端和服务端是对等的,两者都使用 conn 初始化。

          如果需要使用 HTTP 的通讯模式,请使用 HTTPConn 对象。

          func (*Conn) Notify

          func (conn *Conn) Notify(method string, in interface{}) error

            Notify 发送通知信息

            仅发送 in 至服务端,会忽略服务端返回的信息。

            func (*Conn) Send

            func (conn *Conn) Send(method string, in, callback interface{}) error

              Send 发送请求内容

              发送数据 in 至服务,在获得返回数据时,调用 callback 进行处理。 callback 的原型如下:

              func(result interface{}) error
              

              参数 result 必须为一个指针,表示返回的数据对象;且函数返回一个 error。

              func (*Conn) Serve

              func (conn *Conn) Serve(ctx context.Context) (err error)

                Serve 运行服务

                处理 Send 之后的数据或是作为服务端运行都需要调用此函数运行服务。

                ctx 可以用于中断当前的服务。但是需要注意,可能会被 Transport.Read 阻塞而无法退出, 所以在调用 cancel 之后,再下次对方有数据发送过来之后才能会退出。 作为客户端需要下一次的服务端数据下发才能退出, 而作为服务端需下一次的客户端请求才会真正退出。 用户可以自行实现在阻塞时返回 os.ErrDeadlineExceeded 解决此问题。

                type Error

                type Error struct {
                	// 错误代码
                	Code int `json:"code"`
                
                	// 错误的简短描述
                	Message string `json:"message"`
                
                	// 详细的错误描述信息,可以为空
                	Data interface{} `json:"data,omitempty"`
                }

                  Error JSON-RPC 返回的错误类型

                  func NewError

                  func NewError(code int, msg string) *Error

                    NewError 新的 Error 对象

                    func NewErrorWithData

                    func NewErrorWithData(code int, msg string, data interface{}) *Error

                      NewErrorWithData 新的 Error 对象

                      func NewErrorWithError

                      func NewErrorWithError(code int, err error) *Error

                        NewErrorWithError 从 err 构建一个新的 Error 实例

                        如果 err 本身就是 *Error 实例,则会直接返回该对象。

                        func (*Error) Error

                        func (err *Error) Error() string

                        type HTTPConn

                        type HTTPConn struct {
                        	// contains filtered or unexported fields
                        }

                          HTTPConn 表示 json rpc 的 HTTP 服务端中间件

                          func (*HTTPConn) Notify

                          func (h *HTTPConn) Notify(method string, params interface{}) error

                            Notify 请求 JSON RPC 服务端

                            func (*HTTPConn) Send

                            func (h *HTTPConn) Send(method string, params, callback interface{}) error

                              Send 请求 JSON RPC 服务端

                              func (*HTTPConn) ServeHTTP

                              func (h *HTTPConn) ServeHTTP(w http.ResponseWriter, r *http.Request)

                              type ID

                              type ID struct {
                              	// contains filtered or unexported fields
                              }

                                ID 用于表示唯一的请求 ID,可以是数值,字符串

                                func (*ID) Equal

                                func (id *ID) Equal(val *ID) bool

                                  Equal 两个 ID 是否相等

                                  func (*ID) MarshalJSON

                                  func (id *ID) MarshalJSON() ([]byte, error)

                                    MarshalJSON json.Marshaler.MarshalJSON

                                    func (*ID) String

                                    func (id *ID) String() string

                                    func (*ID) UnmarshalJSON

                                    func (id *ID) UnmarshalJSON(data []byte) error

                                      UnmarshalJSON json.Unmarshaler.UnmarshalJSON

                                      type Server

                                      type Server struct {
                                      	// contains filtered or unexported fields
                                      }

                                        Server JSON RPC 服务实例

                                        func NewServer

                                        func NewServer() *Server

                                          NewServer 新的 Server 实例

                                          func (*Server) ErrHandler

                                          func (s *Server) ErrHandler(h func(*Error))

                                            ErrHandler 指定请求数据的错误处理函数

                                            仅针对请求数据,多次调用会相互覆盖。

                                            func (*Server) Exists

                                            func (s *Server) Exists(method string) bool

                                              Exists 是否已经存在相同的方法名

                                              func (*Server) NewConn

                                              func (s *Server) NewConn(t Transport, errlog *log.Logger) *Conn

                                                NewConn 创建长链接的 JSON RPC 实例

                                                t 表示传输层的操作实例; errlog 表示在 serveHTTP 和 Serve 中部分不会中断执行的错误输出。 如果为空,则不会输出这些错误。

                                                func (*Server) NewHTTPConn

                                                func (s *Server) NewHTTPConn(url string, errlog *log.Logger) *HTTPConn

                                                  NewHTTPConn 声明 HTTP 服务端中间件

                                                  NOTE: 作为服务端使用时,如果需要下发数据,则只能与客户端一对一使用。

                                                  url 表示主动请求时的 URL 地址,如果不需要,可以传递空值, 作为客户端时表示服务端的地址,作为服务端使用时,表示客户端的地址; errlog 表示错误日志输出通道,不需要可以为空。

                                                  func (*Server) Register

                                                  func (s *Server) Register(method string, f interface{}) bool

                                                    Register 注册一个新的服务

                                                    f 为处理服务的函数,其原型为以下方式:

                                                    func(notify bool, params, result pointer) error
                                                    

                                                    其中 notify 表示是否为通知类型的请求;params 为用户请求的对象; result 为返回给用户的数据对象;error 则为处理出错是的返回值。 params 和 result 必须为指针类型。

                                                    返回值表示是否添加成功,在已经存在相同值时,会添加失败。

                                                    NOTE: 如果 f 的签名不正确,则会直接 panic

                                                    func (*Server) RegisterBefore

                                                    func (s *Server) RegisterBefore(f func(method string) error)

                                                      RegisterBefore 注册 Before 函数

                                                      f 的原型如下:

                                                      func(method string)(err error)
                                                      

                                                      method RPC 服务名; 如果返回错误值,则会退出 RPC 调用,返回错误尽量采用 *Error 类型;

                                                      NOTE: 如果多次调用,仅最后次启作用。

                                                      func (*Server) RegisterMatcher

                                                      func (s *Server) RegisterMatcher(m func(string) bool, f interface{})

                                                        RegisterMatcher 注册服务名称通过函数判断的新服务

                                                        m 为服务名称的匹配方法,其原型如下:

                                                        func(method string) bool
                                                        

                                                        如果服务名称能正确匹配则返回 true。

                                                        通过 RegisterMatcher 注册的服务,其权重要低于 Register 注册的服务, 即一个服务名称只有在 Register 注册的列表中找不到,才会考虑通过在 RegisterMatcher 注册的列表中查找。

                                                        func (*Server) Registers

                                                        func (s *Server) Registers(methods map[string]interface{})

                                                          Registers 注册多个服务方法

                                                          如果已经存在相同的方法名,则会直接 panic

                                                          type Transport

                                                          type Transport interface {
                                                          	// 从转输层读取内容并转换成对象 v
                                                          	//
                                                          	// 如果返回的是 *Error 类型的错误,则直接将该错误信息反馈给客户端;
                                                          	// 如果是普通错误,则统一转换成 CodeParseError 传递给客户端;
                                                          	// 如果返回的错误符合 errors.Is(err, os.ErrDeadlineExceeded),
                                                          	// 则被忽略作为为无错误处理,同时进行下一轮读取。
                                                          	Read(v interface{}) error
                                                          
                                                          	// 将对象 v 写入传输层
                                                          	//
                                                          	// 如果返回的是 *Error 类型的错误,则直接将该错误信息反馈给客户端,
                                                          	// 如果是普通错误,则错误代码不确定。
                                                          	Write(v interface{}) error
                                                          
                                                          	Close() error
                                                          }

                                                            Transport 用于操作 JSON RPC 的传输层接口

                                                            传输层主要包括了对客户端数据的读写操作。

                                                            func NewSocketTransport

                                                            func NewSocketTransport(header bool, conn net.Conn, timeout time.Duration) Transport

                                                            NewSocketTransport 声明基于 net.Conn 的 Transport 实例

                                                            HTTP、UDP 和 websocket 有专门的实现方法。

                                                            timeout 可以使读取数据时拥有超过的功能。 Conn.Serve() 通过 context.WithCancel 中断当前的服务,但是该功能可能由于 net.Conn.Read() 方法阻塞而无法真正中断服务,timeout 指定了 net.Conn.Read() 方法在无法读取数据是的超时时间。

                                                            func NewStreamTransport

                                                            func NewStreamTransport(header bool, in io.Reader, out io.Writer, close func() error) Transport

                                                              NewStreamTransport 返回基于流的 Transport 实例

                                                              header 是否需要解析报头内容; close 指定了关闭 in 和 out 的函数,如果不需要关闭,则可以传递 nil 值。

                                                              func NewUDPClientTransport

                                                              func NewUDPClientTransport(header bool, raddr, laddr string, timeout time.Duration) (Transport, error)

                                                                NewUDPClientTransport 声明用于客户的 UDP Transport 接口

                                                                这是对 NewUDPTransport 的二次封装,返回适用于客户端的接口实例, 其中的 conn 参数由 net.DialUDP 创建,而 connected 统一为 true。

                                                                raddr 用于指定服务端地址;laddr 用于指定本地地址,可以为空值。 timeout 指定了 udp 在无法读取数据时的超时时间。

                                                                func NewUDPServerTransport

                                                                func NewUDPServerTransport(header bool, addr string, timeout time.Duration) (Transport, error)

                                                                  NewUDPServerTransport 声明用于服务的 UDP Transport 接口

                                                                  这是对 NewUDPTransport 的二次封装,返回适用于服务端的接口实例, 其中的 conn 参数由 net.ListenUDP 创建,而 connected 统一为 false。 timeout 指定了 udp 在无法读取数据时的超时时间。

                                                                  func NewUDPTransport

                                                                  func NewUDPTransport(header bool, conn *net.UDPConn, connected bool, timeout time.Duration) Transport

                                                                    NewUDPTransport 创建 UDP 传输层

                                                                    UDP 作为服务端是无状态的,在客户端发送一次请求之后,才能发送信息给客户端, 且之后如果有新的客户端请求过来,则发送的目标不地址也会变化。在多客户端环境中, 服务端如果有下发数据的行为,接收方是无法保证的。

                                                                    header 表示是否需要输出报头内容目前报头包含了长度和编码两个字段, 如果不包含报头,则是一段合法的 JSON 内容。 connected 表示 conn 是否是有状态的,如果是调用 net.ListenUDP 生成的实例,是无状态的; net.DialUDP 返回的则是有状态的连接。 timeout 指定了 udp 在无法读取数据时的超时时间。

                                                                    func NewWebsocketTransport

                                                                    func NewWebsocketTransport(conn *websocket.Conn) Transport

                                                                      NewWebsocketTransport 声明基于 websocket 的 Transport 实例