Back to godoc.org

Package stmp

v0.0.0-...-7f180d0
Latest Go to latest

The latest major version is .

Published: Jan 14, 2020 | License: MIT | Module: github.com/acrazing/stmp-go

Overview

The golang implementation for STMP framework

STMP is a lightweight real-time bidirectional framework with many highlights. It is a powerful framework to build modularized, proto based real-time application.

Copyright 2020 acrazing <joking.young@gmail.com>. All rights reserved. Since 2020-01-09 15:36:00

Index

Examples

Constants

const (
	MessageKindPing     = 0x0
	MessageKindPong     = 0x1
	MessageKindRequest  = 0x2
	MessageKindNotify   = 0x3
	MessageKindResponse = 0x4
	MessageKindClose    = 0x5
)
const (
	AcceptContentType  = "Accept"
	AcceptEncoding     = "Accept-Encoding"
	AcceptPacketFormat = "Accept-Packet-Format"

	DetermineContentType  = "Content-Type"
	DetermineEncoding     = "Content-Encoding"
	DeterminePacketFormat = "Packet-Format"
	DetermineStmpVersion  = "Stmp-Version"
)
const (
	HandshakeKindServer byte = 0x01
	HandshakeKindClient byte = 0x02
)

Variables

var E_Kind = &proto.ExtensionDesc{
	ExtendedType:  (*descriptor.ServiceOptions)(nil),
	ExtensionType: (*ServiceKind)(nil),
	Field:         5588226,
	Name:          "stmp.kind",
	Tag:           "bytes,5588226,opt,name=kind",
	Filename:      "stmp/stmp.proto",
}
var E_Method = &proto.ExtensionDesc{
	ExtendedType:  (*descriptor.MethodOptions)(nil),
	ExtensionType: (*uint64)(nil),
	Field:         5588226,
	Name:          "stmp.method",
	Tag:           "varint,5588226,opt,name=method",
	Filename:      "stmp/stmp.proto",
}
var E_Service = &proto.ExtensionDesc{
	ExtendedType:  (*descriptor.ServiceOptions)(nil),
	ExtensionType: (*uint64)(nil),
	Field:         5588225,
	Name:          "stmp.service",
	Tag:           "varint,5588225,opt,name=service",
	Filename:      "stmp/stmp.proto",
}
var MapStatus = map[Status]string{
	StatusOk:                    "Ok",
	StatusNetworkError:          "NetworkError",
	StatusProtocolError:         "ProtocolError",
	StatusUnknown:               "Unknown",
	StatusBadRequest:            "BadRequest",
	StatusUnauthorized:          "Unauthorized",
	StatusNotFound:              "NotFound",
	StatusRequestTimeout:        "RequestTimeout",
	StatusRequestEntityTooLarge: "RequestEntityTooLarge",
	StatusTooManyRequests:       "TooManyRequests",
	StatusInternalServerError:   "InternalServerError",
	StatusServerShutdown:        "ServerShutdown",
}
var NotifyOptions = NewCallOptions().ApplyDefault().Notify()

the default notify options, this is used for protoc-gen-stmp

func Async

func Async(ctx context.Context, fn func() (out interface{}, err error))

TODO: dispatch handlers in read channel, and go async when user call Async(ctx, fn) method

func RegisterEncodingCodec

func RegisterEncodingCodec(codecs ...EncodingCodec)

register a new compression algorithm

func RegisterMediaCodec

func RegisterMediaCodec(codecs ...MediaCodec)

register custom media codec

func RegisterMethodAction

func RegisterMethodAction(method string, action uint64, input ModelFactory, output ModelFactory)

register a method, this is used for protoc-gen-stmp

type Backoff

type Backoff interface {
	// the next wait time
	// if should stop, the second value should be false
	// else it should be true
	Next() (wait time.Duration, count int, ok bool)
	// reset the count to 0
	Reset()
}

func NewBackoff

func NewBackoff(base, factor time.Duration, jitter int, limit int) Backoff

jitter is the random time to add or del range limit, from 0 to 100

type Builder

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

func NewBuilder

func NewBuilder() *Builder

func (*Builder) Build

func (sb *Builder) Build() string

func (*Builder) Byte

func (sb *Builder) Byte(b ...byte) *Builder

func (*Builder) Bytes

func (sb *Builder) Bytes(bs ...[]byte) *Builder

func (*Builder) Close

func (sb *Builder) Close() error

func (*Builder) Flush

func (sb *Builder) Flush() error

func (*Builder) Get

func (sb *Builder) Get() []byte

func (*Builder) PBytes

func (sb *Builder) PBytes(bs ...[]byte) *Builder

func (*Builder) PString

func (sb *Builder) PString(s ...string) *Builder

func (*Builder) SBytes

func (sb *Builder) SBytes(bs ...[]byte) *Builder

func (*Builder) SString

func (sb *Builder) SString(s ...string) *Builder

func (*Builder) String

func (sb *Builder) String(s ...string) *Builder

func (*Builder) Uvarint

func (sb *Builder) Uvarint(v uint64) *Builder

func (*Builder) Write

func (sb *Builder) Write(data []byte) (int, error)

type CallOptions

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

the options to make a call

The options to keep response packet.

func ExampleCallOptions_keepPacket() {
    p := stmp.NewPacket()
    someClient.DoSomething(ctx, input, stmp.NewCallOptions().KeepPacket(p))
    log.Printf("Kind=%d, Mid=%d, Status=%d, Payload=%s.", p.Kind, p.Mid, p.Status, string(p.Payload))
    // Output: Kind=4, Mid=1, Status=0, Payload=.
}

func NewCallOptions

func NewCallOptions() *CallOptions

create a default call options

func PickCallOptions

func PickCallOptions(opts ...*CallOptions) *CallOptions

pick the first call options, if the input is empty, will build a default options

func (*CallOptions) ApplyDefault

func (o *CallOptions) ApplyDefault() *CallOptions

set default options

func (*CallOptions) KeepPacket

func (o *CallOptions) KeepPacket(p *Packet) *CallOptions

keep response packet, you can get the raw information from the packet

func (*CallOptions) Notify

func (o *CallOptions) Notify() *CallOptions

call with notify, which means the conn will not wait for the response

func (*CallOptions) PreferStringAction

func (o *CallOptions) PreferStringAction() *CallOptions

type Client

type Client struct {
	*Router
	*Conn
	// contains filtered or unexported fields
}

client conn

Example

Code:

package main

import (
	"github.com/acrazing/stmp-go/stmp"
	"log"
	"time"
)

func main() {
	sc := stmp.NewClient(nil)
	sc.HandleConnected(func(header stmp.Header, message string) {
		log.Printf("stmp connected: %q.", message)
		time.Sleep(time.Second)
		// the connection will auto reconnect by default
		sc.Close(stmp.StatusNetworkError, "test retry")
	})
	sc.HandleDisconnected(func(reason stmp.StatusError, willRetry bool, retryCount int, retryWait time.Duration) {
		log.Printf("stmp disconnected, reason: %q, will retry: %t the %d time in %d seconds.", reason, willRetry, retryCount, retryWait)
	})
	sc.DialTCP("127.0.0.1:9991")
}

func NewClient

func NewClient(opts *ClientOptions) *Client

func SelectClient

func SelectClient(ctx context.Context) *Client

func (*Client) DialKCP

func (c *Client) DialKCP(addr string)

dial method will create *Conn, and setup, and handshake, and serve

func (*Client) DialKCPWithTLS

func (c *Client) DialKCPWithTLS(addr string)

func (*Client) DialTCP

func (c *Client) DialTCP(addr string)

dial method will create *Conn, and setup, and handshake, and serve

func (*Client) DialTCPWithTLS

func (c *Client) DialTCPWithTLS(addr string)

dial method will create *Conn, and setup, and handshake, and serve

func (*Client) DialWebsocket

func (c *Client) DialWebsocket(urlstr string)

func (*Client) HandleConnected

func (c *Client) HandleConnected(fn func(header Header, message string))

func (*Client) HandleDisconnected

func (c *Client) HandleDisconnected(fn func(reason StatusError, willRetry bool, retryCount int, retryWait time.Duration))

func (*Client) Status

func (c *Client) Status() ClientStatus

type ClientOptions

type ClientOptions struct {
	*ConnOptions
	// contains filtered or unexported fields
}

func NewClientOptions

func NewClientOptions() *ClientOptions

create dial options

func (*ClientOptions) ApplyDefault

func (o *ClientOptions) ApplyDefault() *ClientOptions

apply default configuration, you do not to call this when call DialXXX(addr, opts) only when you want to create ClientConn by call NewClientConn(net.Conn, opts) you should call this.

func (*ClientOptions) WithCompress

func (o *ClientOptions) WithCompress(level int) *ClientOptions

func (*ClientOptions) WithContentType

func (o *ClientOptions) WithContentType(typ string) *ClientOptions

set the payload content type, available values are application/json, application/protobuf, application/msgpack you can implement custom MediaCodec and register it both server and client side to activate it.

func (*ClientOptions) WithEncoding

func (o *ClientOptions) WithEncoding(name string) *ClientOptions

enable compress, only available algorithm is gzip, you can implement your custom algorithm with EncodingCodec interface, and register it with RegisterEncodingCodec (both server and client side need to register it) only supports tcp/kcp connections, websocket cannot use this

func (*ClientOptions) WithHeader

func (o *ClientOptions) WithHeader(key string, value string) *ClientOptions

set a custom handshake header

func (*ClientOptions) WithLogger

func (o *ClientOptions) WithLogger(logger *zap.Logger) *ClientOptions

set logger for client, default is zap.NewProduction()

func (*ClientOptions) WithPacketFormat

func (o *ClientOptions) WithPacketFormat(format string) *ClientOptions

packet format, only for websocket, could be text or binary, default is binary

func (*ClientOptions) WithPacketSizeLimit

func (o *ClientOptions) WithPacketSizeLimit(max uint64) *ClientOptions

the max message packet size, include handshake, exchange, close message, default is 16mb

func (*ClientOptions) WithProtocolVersion

func (o *ClientOptions) WithProtocolVersion(major byte, minor byte) *ClientOptions

func (*ClientOptions) WithReconnect

func (o *ClientOptions) WithReconnect(backoff Backoff) *ClientOptions

enable or disable reconnect if backoff is nil, will not reconnect else will retry when network error delay with backoff

func (*ClientOptions) WithResolver

func (o *ClientOptions) WithResolver(r *net.Resolver) *ClientOptions

set custom resolver if addr is host:port

func (*ClientOptions) WithTLS

func (o *ClientOptions) WithTLS(certFile string, serverName string, skipVerify bool) *ClientOptions

Se necessary elements for build a custom tls.Config

If skipVerify is true, serverName is omitted, else if serverName is empty, the input addr of DialXxxWithTLS must be a host:port rather than ip:port

func (*ClientOptions) WithTLSConfig

func (o *ClientOptions) WithTLSConfig(config *tls.Config) *ClientOptions

set custom tls config, if this is set, certFile and skipVerify will be omitted

func (*ClientOptions) WithTimeout

func (o *ClientOptions) WithTimeout(handshake, read, write time.Duration) *ClientOptions

set timeout for handshake and exchange the read means at least one packet should be received in this time client will auto send ping message with the interval, if client do not receive pong from server in this time, client will close with StatusNetworkError

func (*ClientOptions) WithWriteQueueLimit

func (o *ClientOptions) WithWriteQueueLimit(max int) *ClientOptions

the max pending write packet size, default is 8

type ClientStatus

type ClientStatus int32
const (
	StatusDisconnected ClientStatus = 1
	StatusConnecting   ClientStatus = 2
	StatusConnected    ClientStatus = 3
	StatusClosing      ClientStatus = 4
)

type Conn

type Conn struct {
	net.Conn
	State

	// the stmp major version
	Major byte
	// the stmp minor version
	Minor byte

	// the content-type codec
	Media MediaCodec

	// client handshake request header
	ClientHeader Header
	// server handshake response header
	ServerHeader Header
	// contains filtered or unexported fields
}

the struct will only keep the required fields for the connection to save space at server side

func NewConn

func NewConn(nc net.Conn, opts *ConnOptions) *Conn

create a conn from net.Conn and options

func SelectConn

func SelectConn(ctx context.Context) *Conn

func (*Conn) Call

func (c *Conn) Call(ctx context.Context, method string, payload []byte, opts *CallOptions) (out interface{}, err error)

invoke a method a marshaled payload

func (*Conn) Close

func (c *Conn) Close(status Status, message string) (err error)

close the connection manually

func (*Conn) Invoke

func (c *Conn) Invoke(ctx context.Context, method string, in interface{}, opts *CallOptions) (interface{}, error)

invoke a method with raw input, will marshal it with conn's media codec

type ConnCloseHandler

type ConnCloseHandler func(conn *Conn, status Status, message string)

type ConnFilter

type ConnFilter func(conn *Conn) bool
var AllowAll ConnFilter = func(conn *Conn) bool { return true }

type ConnOptions

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

the connection configurations

func NewConnOptions

func NewConnOptions() *ConnOptions

create a new conn options

func (*ConnOptions) ApplyDefault

func (o *ConnOptions) ApplyDefault() *ConnOptions

build final options, check default options

func (*ConnOptions) PreferStringAction

func (o *ConnOptions) PreferStringAction() *ConnOptions

func (*ConnOptions) WithCompress

func (o *ConnOptions) WithCompress(level int) *ConnOptions

func (*ConnOptions) WithLogger

func (o *ConnOptions) WithLogger(logger *zap.Logger) *ConnOptions

set custom logger, default is zap.NewProduction()

func (*ConnOptions) WithPacketSizeLimit

func (o *ConnOptions) WithPacketSizeLimit(max uint64) *ConnOptions

set the max packet size, default is 16mb

func (*ConnOptions) WithTimeout

func (o *ConnOptions) WithTimeout(handshake, read, write time.Duration) *ConnOptions

set timeouts, the read timeout means ping interval

func (*ConnOptions) WithWriteQueueLimit

func (o *ConnOptions) WithWriteQueueLimit(max int) *ConnOptions

set max write queue size, default is 8

type ConnSet

type ConnSet map[*Conn]struct{}

A connection set util to hold as group

func NewConnSet

func NewConnSet() ConnSet

create a new connection set

func (ConnSet) Add

func (s ConnSet) Add(conn *Conn)

add conn to set

func (ConnSet) Del

func (s ConnSet) Del(conn *Conn)

remove a conn

func (ConnSet) Has

func (s ConnSet) Has(conn *Conn) bool

check has conn or not

func (ConnSet) Size

func (s ConnSet) Size() int

the size of the set

func (ConnSet) Slice

func (s ConnSet) Slice() []*Conn

transform to a slice

type EncodingCodec

type EncodingCodec interface {
	Name() string
	Reader(r io.Reader) (io.ReadCloser, error)
	Writer(w io.Writer, level int) (EncodingWriter, error)
}

func GetEncodingCodec

func GetEncodingCodec(name string) EncodingCodec

func NewGzipCodec

func NewGzipCodec() EncodingCodec

type EncodingWriter

type EncodingWriter interface {
	io.WriteCloser
	Flush() error
}

type HandlerFunc

type HandlerFunc func(ctx context.Context, in interface{}, inst interface{}) (out interface{}, err error)

type Handshake

type Handshake struct {
	Kind    byte
	Major   byte
	Minor   byte
	Status  Status
	Header  Header
	Message string
}

func NewClientHandshake

func NewClientHandshake(major, minor byte, header Header, message string) *Handshake

func NewServerHandshake

func NewServerHandshake(status Status, header Header, message string) *Handshake

func (*Handshake) MarshalBinary

func (h *Handshake) MarshalBinary() []byte

func (*Handshake) MarshalHead

func (h *Handshake) MarshalHead() (title []byte, header []byte)

func (*Handshake) MarshalText

func (h *Handshake) MarshalText() []byte

server only

func (*Handshake) Read

func (h *Handshake) Read(r io.Reader, limit uint64) StatusError

func (*Handshake) UnmarshalBinary

func (h *Handshake) UnmarshalBinary(data []byte) StatusError

client only

func (*Handshake) UnmarshalText

func (h *Handshake) UnmarshalText(data []byte) StatusError

client only

func (*Handshake) Write

func (h *Handshake) Write(w io.Writer) StatusError
type Header map[string][]string

func NewHeader

func NewHeader() Header

func SelectInputHeader

func SelectInputHeader(ctx context.Context) Header

func SelectOutputHeader

func SelectOutputHeader(ctx context.Context) Header

func (Header) Add

func (h Header) Add(key string, value string)

func (Header) Clear

func (h Header) Clear()

func (Header) Del

func (h Header) Del(key string)

func (Header) Get

func (h Header) Get(key string) string

func (Header) GetAll

func (h Header) GetAll(key string) []string

func (Header) Has

func (h Header) Has(key string) bool

func (Header) Marshal

func (h Header) Marshal() []byte

func (Header) Set

func (h Header) Set(key string, value string)

func (Header) Unmarshal

func (h Header) Unmarshal(data []byte) error

type InterceptFunc

type InterceptFunc func(inCtx context.Context) (outCtx context.Context, done bool, out []byte, err error)

type ListenerFunc

type ListenerFunc func(ctx context.Context, in interface{}, inst interface{})

type MediaCodec

type MediaCodec interface {
	Name() string
	Marshal(v interface{}) ([]byte, error)
	Unmarshal(data []byte, v interface{}) error
}

A media codec should Marshal/Unmarshal its Name specified content-type

func GetMediaCodec

func GetMediaCodec(name string) MediaCodec

get media codec by content type

func NewJsonCodec

func NewJsonCodec() MediaCodec

create json codec

func NewMsgpackCodec

func NewMsgpackCodec() MediaCodec

create msgpack codec

func NewProtobufCodec

func NewProtobufCodec() MediaCodec

create protobuf codec

type Method

type Method struct {
	Method    string
	Action    uint64
	ActionHex string
	Input     ModelFactory
	Output    ModelFactory
}

method information, for middleware and interceptors

func SelectMethod

func SelectMethod(ctx context.Context) *Method

type ModelFactory

type ModelFactory func() interface{}

the model factory should create instance of input/output, it is used for protoc-gen-stmp

type Packet

type Packet struct {
	Kind         byte
	WithPayload  bool
	WithHeader   bool
	StringAction bool
	Status       Status
	Mid          uint16
	Action       uint64
	Method       string
	Header       Header
	Payload      []byte
}

func NewClosePacket

func NewClosePacket(status Status, message string) *Packet

func SelectPacket

func SelectPacket(ctx context.Context) *Packet

func (*Packet) BinarySize

func (p *Packet) BinarySize(ps bool) (header []byte, size int)

func (*Packet) HasAction

func (p *Packet) HasAction() bool

func (*Packet) HasHeader

func (p *Packet) HasHeader() bool

func (*Packet) HasMid

func (p *Packet) HasMid() bool

func (*Packet) HasPayload

func (p *Packet) HasPayload() bool

func (*Packet) HasStatus

func (p *Packet) HasStatus() bool

func (*Packet) MarshalBinary

func (p *Packet) MarshalBinary() []byte

func (*Packet) MarshalHead

func (p *Packet) MarshalHead(ps bool) []byte

func (*Packet) MarshalText

func (p *Packet) MarshalText() []byte

func (*Packet) Read

func (p *Packet) Read(r io.Reader, maxPacketSize uint64) StatusError

func (*Packet) UnmarshalBinary

func (p *Packet) UnmarshalBinary(data []byte) StatusError

func (*Packet) UnmarshalHead

func (p *Packet) UnmarshalHead(h byte) StatusError

func (*Packet) UnmarshalText

func (p *Packet) UnmarshalText(data []byte) StatusError

func (*Packet) Write

func (p *Packet) Write(w EncodingWriter) StatusError

type PayloadMap

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

payload map will cache the marshalled data for the same content-type

func NewPayloadMap

func NewPayloadMap(in interface{}) *PayloadMap

create a new PayloadMap

func (*PayloadMap) Marshal

func (p *PayloadMap) Marshal(conn *Conn) ([]byte, error)

marshal and cache the result according to the content type

type PostHandlerFunc

type PostHandlerFunc func(ctx context.Context, status Status, header Header, payload []byte) error

type PreHandlerFunc

type PreHandlerFunc func(inCtx context.Context) (outCtx context.Context, err error)

type Router

type Router struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Core router for dispatch a request

The process order is: pre -> interceptor -> handler -> post -> response -> listener

Please note the handler is not routine-safe

func NewRouter

func NewRouter(host interface{}) *Router

Create a router

The host is a *Server or *Client, which is used for create a stmp context you can use SelectServer(ctx) or SelectClient(ctx) to get it in handler

func (*Router) AddListener

func (r *Router) AddListener(method string, inst interface{}, fn ListenerFunc)

Add a listener, which is executed after response

func (*Router) Handle

func (r *Router) Handle(method string, inst interface{}, fn HandlerFunc)

Add a handler, which is executed after interceptor, and before post handler, it is the core handler to generate the response packet.

Please note the handlers of pre, interceptor, handler, post, listener is executed serially in the read channel, which means it will block the read from the connection, so it should run A.S.A.P.

func (*Router) Intercept

func (r *Router) Intercept(handlers ...InterceptFunc)

Add an interceptor, which is executed after pre, and before handler

func (*Router) Post

func (r *Router) Post(handlers ...PostHandlerFunc)

Add a post handler, which is executed just before response the packet, it could emit an error to change the response status and payload, or update the response header

func (*Router) Pre

func (r *Router) Pre(handlers ...PreHandlerFunc)

Add a pre handler, which is executed at fist, and could update the context or stop the dispatch chain by emit an error

func (*Router) RemoveListener

func (r *Router) RemoveListener(method string, inst interface{})

Remove a listener

type Server

type Server struct {
	*Router
	// contains filtered or unexported fields
}
Example (ListenMultiple)

Code:

package main

import (
	"github.com/acrazing/stmp-go/stmp"
	"log"
)

func main() {
	srv := stmp.NewServer(stmp.NewServerOptions())
	go srv.ListenAndServeTCP("127.0.0.1:9991")
	log.Printf("stmp server is listening at %q.", "tcp://127.0.0.1:9991")
	go srv.ListenAndServeWebsocket("127.0.0.1:9992", "/stmp")
	log.Printf("stmp server is listening at %q.", "ws://127.0.0.1:9992/stmp")
	go srv.ListenAndServeKCPWithTLS("127.0.0.1:9993", "./example.crt", "./example.key")
	log.Printf("stmp server is listening at %q.", "kcp+tls://127.0.0.1:9992")
	err := srv.Wait()
	if err != nil {
		log.Fatalf("stmp server listen error: %q.", err)
	} else {
		log.Println("stmp server shutdown.")
	}
}

func NewServer

func NewServer(opts *ServerOptions) *Server

func SelectServer

func SelectServer(ctx context.Context) *Server

func (*Server) Broadcast

func (s *Server) Broadcast(ctx context.Context, method string, in interface{}, filters ...ConnFilter)

func (*Server) Close

func (s *Server) Close()

close all listeners

func (*Server) HandleConn

func (s *Server) HandleConn(nc net.Conn) (err error)

serve net conn

func (*Server) HandleConnClose

func (s *Server) HandleConnClose(fn ConnCloseHandler)

func (*Server) HandleWebsocketConn

func (s *Server) HandleWebsocketConn(wc *websocket.Conn, req *http.Request) (err error)

serve websocket conn

func (*Server) ListenAndServeKCP

func (s *Server) ListenAndServeKCP(addr string)

func (*Server) ListenAndServeKCPWithTLS

func (s *Server) ListenAndServeKCPWithTLS(addr string, certFile, keyFile string)

func (*Server) ListenAndServeTCP

func (s *Server) ListenAndServeTCP(addr string)

func (*Server) ListenAndServeTCPWithTLS

func (s *Server) ListenAndServeTCPWithTLS(addr string, certFile, keyFile string)

func (*Server) ListenAndServeWebsocket

func (s *Server) ListenAndServeWebsocket(addr, path string)

func (*Server) ListenAndServeWebsocketWithTLS

func (s *Server) ListenAndServeWebsocketWithTLS(addr, path, certFile, keyFile string)

func (*Server) Serve

func (s *Server) Serve(lis net.Listener)

serve a net listener

func (*Server) Wait

func (s *Server) Wait() error

wait server close, this should call once at most, it returns when server listen error occurs or call close method

if err is not nil, means the listener meet an error, else means the server is closed manually

type ServerOptions

type ServerOptions struct {
	*ConnOptions
	// contains filtered or unexported fields
}

func NewServerOptions

func NewServerOptions() *ServerOptions

func (*ServerOptions) ApplyDefault

func (o *ServerOptions) ApplyDefault() *ServerOptions

func (*ServerOptions) WithAuthenticate

func (o *ServerOptions) WithAuthenticate(fn func(c *Conn) error) *ServerOptions

func (*ServerOptions) WithCompress

func (o *ServerOptions) WithCompress(level int) *ServerOptions

func (*ServerOptions) WithLogAccess

func (o *ServerOptions) WithLogAccess(fields ...string) *ServerOptions

func (*ServerOptions) WithLogger

func (o *ServerOptions) WithLogger(logger *zap.Logger) *ServerOptions

func (*ServerOptions) WithPacketSizeLimit

func (o *ServerOptions) WithPacketSizeLimit(max uint64) *ServerOptions

func (*ServerOptions) WithTimeout

func (o *ServerOptions) WithTimeout(handshake, read, write time.Duration) *ServerOptions

func (*ServerOptions) WithWriteQueueLimit

func (o *ServerOptions) WithWriteQueueLimit(max int) *ServerOptions

type ServiceKind

type ServiceKind struct {
	Service              bool     `protobuf:"varint,1,opt,name=service,proto3" json:"service,omitempty"`
	Events               bool     `protobuf:"varint,2,opt,name=events,proto3" json:"events,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

the service kind if service is true, will generate server api, such as STMPRegisterXxxServer, STMPXxxClient if events is true, will generate events api, such as STMPRegisterXxxListener, STMPXxxBroadcaster if both not set, will detect by service name suffix if ends with Service, will treat as service else if ends with Events, will treat as events else both will be true default

func (*ServiceKind) Descriptor

func (*ServiceKind) Descriptor() ([]byte, []int)

func (*ServiceKind) GetEvents

func (m *ServiceKind) GetEvents() bool

func (*ServiceKind) GetService

func (m *ServiceKind) GetService() bool

func (*ServiceKind) ProtoMessage

func (*ServiceKind) ProtoMessage()

func (*ServiceKind) Reset

func (m *ServiceKind) Reset()

func (*ServiceKind) String

func (m *ServiceKind) String() string

func (*ServiceKind) XXX_DiscardUnknown

func (m *ServiceKind) XXX_DiscardUnknown()

func (*ServiceKind) XXX_Marshal

func (m *ServiceKind) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*ServiceKind) XXX_Merge

func (m *ServiceKind) XXX_Merge(src proto.Message)

func (*ServiceKind) XXX_Size

func (m *ServiceKind) XXX_Size() int

func (*ServiceKind) XXX_Unmarshal

func (m *ServiceKind) XXX_Unmarshal(b []byte) error

type State

type State struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewState

func NewState() State

func (State) Del

func (s State) Del(key interface{})

func (State) DelUnsafe

func (s State) DelUnsafe(key interface{})

func (State) Get

func (s State) Get(key interface{}) interface{}

func (State) GetUnsafe

func (s State) GetUnsafe(key interface{}) interface{}

func (State) Has

func (s State) Has(key interface{}) interface{}

func (State) HasUnsafe

func (s State) HasUnsafe(key interface{}) interface{}

func (State) Set

func (s State) Set(key, value interface{})

func (State) SetUnsafe

func (s State) SetUnsafe(key, value interface{})

type Status

type Status byte
const (
	// OK
	// for handshake, if status is not OK, will close directly
	StatusOk Status = 0x00
	// unknown
	StatusUnknown Status = 0x01
	// network error
	// sender write, sender read
	// receiver read or write error will omit the request
	// maybe timeout to close
	StatusNetworkError Status = 0x02
	// protocol error
	// for parse packet error
	StatusProtocolError Status = 0x03
	// sender error
	// for handshake, maybe: unsupported packet format, protocol version, content type, encoding
	// for requests, maybe: sender cannot marshal input, receiver unmarshal input error, handler emit
	StatusBadRequest Status = 0x20
	// authenticate error, or handler emit
	StatusUnauthorized Status = 0x21
	// action is not registered, or interceptors do not accept, or no registered handlers
	StatusNotFound Status = 0x22
	// sender cancelled, which means ctx.Done() returns before receive response
	StatusRequestTimeout Status = 0x23
	// packet too large, if is request, will send close with this status
	StatusRequestEntityTooLarge Status = 0x24
	// rate limit, not implemented
	StatusTooManyRequests Status = 0x25
	// server internal error
	// marshal output error, handler emit error
	StatusInternalServerError Status = 0x40
	// close connection when server close
	StatusServerShutdown Status = 0x41
)

func (Status) Code

func (s Status) Code() Status

func (Status) Error

func (s Status) Error() string

func (Status) Message

func (s Status) Message() string

func (Status) Spread

func (s Status) Spread() (Status, []byte)

type StatusError

type StatusError interface {
	Error() string
	Spread() (Status, []byte)
	Code() Status
	Message() string
}

a status error

func DetectError

func DetectError(err error, fallback Status) StatusError

Detect handler emitted error

If the err is StatusError, will use it directly else will use the fallback as the status

func NewStatusError

func NewStatusError(code Status, data interface{}) StatusError

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier