gobayeux

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2020 License: Apache-2.0 Imports: 15 Imported by: 0

README

gobayeux

PkgGoDev Test Build golangci-lint

Bayeux protocol library compatible with CometD and Faye servers.

Documentation
Installation
go get github.com/L11R/gobayeux
Status

Library provides a basic set of features to start getting notification over long-polling transport.

Protocol compliance
  • Handshake
  • Connect/Disconnect
  • Subscribe/Unsubscribe
  • Publish and Delivery event messages
  • The long-polling transport
  • The callback-polling transport
  • The websocket transport
Authors
  • @sigmavirus24
  • @L11R
License

Apache 2.0

Documentation

Index

Examples

Constants

View Source
const (
	// ConnectionTypeLongPolling is a constant for the long-polling string
	ConnectionTypeLongPolling string = "long-polling"
	// ConnectionTypeCallbackPolling is a constant for the callback-polling string
	ConnectionTypeCallbackPolling = "callback-polling"
	// ConnectionTypeIFrame is a constant for the iframe string
	ConnectionTypeIFrame = "iframe"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Advice

type Advice struct {
	// Reconnect indicates how the client should act in the case of a failure
	// to connect.
	//
	// See also: https://docs.cometd.org/current/reference/#_reconnect_advice_field
	Reconnect string `json:"reconnect,omitempty"`
	// Timeout represents the period of time, in milliseconds, for the server
	// to delay requests to the `/meta/connect` channel.
	//
	// See also: https://docs.cometd.org/current/reference/#_timeout_advice_field
	Timeout int `json:"timeout,omitempty"`
	// Interval represents the minimum period of time, in milliseconds, for the
	// client to delay subsequent requests to the /meta/connect channel.
	//
	// See also: https://docs.cometd.org/current/reference/#_interval_advice_field
	Interval int `json:"interval,omitempty"`
	// MultipleClients indicates that the server has detected multiple Bayeux
	// client instances running within the same web client
	//
	// See also: https://docs.cometd.org/current/reference/#_bayeux_multiple_clients_advice
	MultipleClients bool `json:"multiple-clients,omitempty"`
	// Hosts is an array of strings which if present indicates a list of host
	// names or IP addresses that MAY be used as alternate servers. If a
	// re-handshake advice is received by a client and the current server is
	// not in the supplied hosts list, then the client SHOULD try the hosts in
	// order.
	//
	// See also: https://docs.cometd.org/current/reference/#_hosts_advice_field
	Hosts []string `json:"hosts,omitempty"`
}

Advice represents the field from the server which is used to inform clients of their preferred mode of client operation.

See also: https://docs.cometd.org/current/reference/#_bayeux_advice

func (Advice) IntervalAsDuration

func (a Advice) IntervalAsDuration() time.Duration

IntervalAsDuration returns the Timeout field as a time.Duration for scheduling

func (Advice) MustNotRetryOrHandshake

func (a Advice) MustNotRetryOrHandshake() bool

MustNotRetryOrHandshake indicates whether neither a handshake or retry is allowed

func (Advice) ShouldHandshake

func (a Advice) ShouldHandshake() bool

ShouldHandshake indicates whether the advice is that a handshake should occur

func (Advice) ShouldRetry

func (a Advice) ShouldRetry() bool

ShouldRetry indicates whether a retry should occur

func (Advice) TimeoutAsDuration

func (a Advice) TimeoutAsDuration() time.Duration

TimeoutAsDuration returns the Timeout field as a time.Duration for scheduling

type BayeuxClient

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

BayeuxClient is a way of acting as a client with a given Bayeux server

func NewBayeuxClient

func NewBayeuxClient(client *http.Client, transport *http.Transport, serverAddress string, logger logrus.FieldLogger) (*BayeuxClient, error)

NewBayeuxClient initializes a BayeuxClient for the user

func (*BayeuxClient) Connect

func (b *BayeuxClient) Connect(ctx context.Context) ([]Message, error)

Connect sends the connect request to the Bayeux Server. The specification says that clients MUST maintain only one outstanding connect request. See https://docs.cometd.org/current/reference/#_bayeux_meta_connect

func (*BayeuxClient) Disconnect

func (b *BayeuxClient) Disconnect(ctx context.Context) ([]Message, error)

Disconnect sends a /meta/disconnect request to the Bayeux server to terminate the session

func (*BayeuxClient) Handshake

func (b *BayeuxClient) Handshake(ctx context.Context) ([]Message, error)

Handshake sends the handshake request to the Bayeux Server

func (*BayeuxClient) Subscribe

func (b *BayeuxClient) Subscribe(ctx context.Context, subscriptions []Channel) ([]Message, error)

Subscribe issues a MetaSubscribe request to the server to subscribe to the channels in the subscriptions slice

func (*BayeuxClient) Unsubscribe

func (b *BayeuxClient) Unsubscribe(ctx context.Context, subscriptions []Channel) ([]Message, error)

Unsubscribe issues a MetaUnsubscribe request to the server to subscribe to the channels in the subscriptions slice

type Channel

type Channel string

Channel represents a Bayeux Channel which is defined as "a string that looks like a URL path such as `/foo/bar`, `/meta/connect`, or `/service/chat`."

See also: https://docs.cometd.org/current/reference/#_concepts_channels

const (
	// MetaHandshake is the Channel for the first message a new client sends.
	MetaHandshake Channel = "/meta/handshake"
	// MetaConnect is the Channel used for connect messages after a successful
	// handshake.
	MetaConnect Channel = "/meta/connect"
	// MetaDisconnect is the Channel used for disconnect messages.
	MetaDisconnect Channel = "/meta/disconnect"
	// MetaSubscribe is the Channel used by a client to subscribe to channels.
	MetaSubscribe Channel = "/meta/subscribe"
	// MetaUnsubscribe is the Channel used by a client to unsubscribe to
	// channels.
	MetaUnsubscribe Channel = "/meta/unsubscribe"
)

func (Channel) HasWildcard

func (c Channel) HasWildcard() bool

HasWildcard indicates whether the Channel ends with * or **

See also: https://docs.cometd.org/current/reference/#_concepts_channels_wild

func (Channel) IsValid

func (c Channel) IsValid() bool

IsValid does its best to check the validity of a Channel

func (Channel) Match

func (c Channel) Match(other Channel) bool

Match checks if a given Channel matches this Channel. Note wildcards are only valid after the last /.

See also: https://docs.cometd.org/current/reference/#_concepts_channels_wild

func (Channel) MatchString

func (c Channel) MatchString(other string) bool

MatchString checks if a given string matches this Channel. Note wildcards are only valid after the last /.

See also: https://docs.cometd.org/current/reference/#_concepts_channels_wild

func (Channel) Type

func (c Channel) Type() ChannelType

Type provides the type of Channel this struct represents

type ChannelType

type ChannelType string

ChannelType is used to define the three types of channels: - meta channels, channels starting with `/meta/` - service channels, channels starting with `/service/` - broadcast channels, all other channels

const (
	// MetaChannel represents the `/meta/` channel type
	MetaChannel ChannelType = "meta"
	// ServiceChannel represents the `/service/` channel type
	ServiceChannel ChannelType = "service"
	// BroadcastChannel represents all other channels
	BroadcastChannel ChannelType = "broadcast"
)

type Client

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

Client is a high-level abstraction

func NewClient

func NewClient(serverAddress string, opts ...Option) (*Client, error)

NewClient creates a new high-level client

func (*Client) Disconnect

func (c *Client) Disconnect(ctx context.Context) error

Disconnect issues a /meta/disconnect request to the Bayeux server and then cleans up channels and our timer.

func (*Client) Publish

func (c *Client) Publish(ctx context.Context, messages []Message) error

Publish is not yet implemented. When implemented, it will - in a separate thread from the polling task - publish messages to the Bayeux Server.

See also: https://docs.cometd.org/current/reference/#_two_connection_operation

func (*Client) Start

func (c *Client) Start(ctx context.Context) <-chan error

Start begins the background process that talks to the server

func (*Client) Subscribe

func (c *Client) Subscribe(ch Channel, receiving chan []Message)

Subscribe queues a request to subscribe to a new channel from the server

type ConnectRequestBuilder

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

ConnectRequestBuilder provides a way to safely build a Message that can be sent as a /meta/connect request as documented in https://docs.cometd.org/current/reference/#_connect_request

Example
b := NewConnectRequestBuilder()
if err := b.AddConnectionType(ConnectionTypeLongPolling); err != nil {
	return
}
b.AddClientID("Un1q31d3nt1f13r")
m, err := b.Build()
if err != nil {
	return
}
jsonBytes, err := json.Marshal(m)
if err != nil {
	return
}
fmt.Println(string(jsonBytes))
Output:

[{"channel":"/meta/connect","clientId":"Un1q31d3nt1f13r","connectionType":"long-polling"}]

func NewConnectRequestBuilder

func NewConnectRequestBuilder() *ConnectRequestBuilder

NewConnectRequestBuilder initializes a ConnectRequestBuilder as an easy way to build a Message that can be sent as a /meta/connect request. See also: https://docs.cometd.org/current/reference/#_connect_request

func (*ConnectRequestBuilder) AddClientID

func (b *ConnectRequestBuilder) AddClientID(clientID string)

AddClientID adds the previously provided clientId to the request

func (*ConnectRequestBuilder) AddConnectionType

func (b *ConnectRequestBuilder) AddConnectionType(connectionType string) error

AddConnectionType adds the connection type used by the client for the purposes of this connection to the request

func (*ConnectRequestBuilder) Build

func (b *ConnectRequestBuilder) Build() ([]Message, error)

Build generates the final Message to be sent as a Connect Request

type ConnectionStateMachine

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

ConnectionStateMachine handles managing the connection's state

See also: https://docs.cometd.org/current/reference/#_client_state_table

func NewConnectionStateMachine

func NewConnectionStateMachine() *ConnectionStateMachine

NewConnectionStateMachine creates a new ConnectionStateMachine to manage a connection's state

func (*ConnectionStateMachine) CurrentState

func (csm *ConnectionStateMachine) CurrentState() StateRepresentation

CurrentState provides a string representation of the current state of the state machine

func (*ConnectionStateMachine) IsConnected

func (csm *ConnectionStateMachine) IsConnected() bool

IsConnected reflects whether the connection is connected to the Bayeux server

func (*ConnectionStateMachine) ProcessEvent

func (csm *ConnectionStateMachine) ProcessEvent(e Event) error

ProcessEvent handles an event

type DisconnectRequestBuilder

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

DisconnectRequestBuilder provides an easy way to build a /meta/disconnect request per the specification in https://docs.cometd.org/current/reference/#_bayeux_meta_disconnect

func NewDisconnectRequestBuilder

func NewDisconnectRequestBuilder() *DisconnectRequestBuilder

NewDisconnectRequestBuilder initializes a DisconnectRequestBuilder as an easy way to build a Message that can be sent as a /meta/disconnect request.

func (*DisconnectRequestBuilder) AddClientID

func (b *DisconnectRequestBuilder) AddClientID(clientID string)

AddClientID adds the previously provided clientId to the request

func (*DisconnectRequestBuilder) Build

func (b *DisconnectRequestBuilder) Build() ([]Message, error)

Build generates the final Message to be sent as a Disconnect Request

type Event

type Event string

Event represents and event that can change the state of a state machine

type HandshakeRequestBuilder

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

HandshakeRequestBuilder provides a way to safely and confidently create handshake requests to /meta/handshake.

See also: https://docs.cometd.org/current/reference/#_handshake_request

Example
b := NewHandshakeRequestBuilder()
if err := b.AddSupportedConnectionType(ConnectionTypeLongPolling); err != nil {
	return
}
if err := b.AddVersion("1.0"); err != nil {
	return
}
m, err := b.Build()
if err != nil {
	return
}
jsonBytes, err := json.Marshal(m)
if err != nil {
	return
}
fmt.Println(string(jsonBytes))
Output:

[{"channel":"/meta/handshake","version":"1.0","supportedConnectionTypes":["long-polling"]}]

func NewHandshakeRequestBuilder

func NewHandshakeRequestBuilder() *HandshakeRequestBuilder

NewHandshakeRequestBuilder provides an easy way to build a Message that can be sent as a Handshake Request as documented in https://docs.cometd.org/current/reference/#_handshake_request

func (*HandshakeRequestBuilder) AddMinimumVersion

func (b *HandshakeRequestBuilder) AddMinimumVersion(version string) error

AddMinimumVersion adds the minimum supported version

func (*HandshakeRequestBuilder) AddSupportedConnectionType

func (b *HandshakeRequestBuilder) AddSupportedConnectionType(connectionType string) error

AddSupportedConnectionType accepts a string and will add it to the list of supported connection types for the /meta/handshake request. It validates the connection type. You're encouraged to use one of the constants created for these different connection types. This will de-duplicate connection types and returns an error if an invalid connection type was provided.

func (*HandshakeRequestBuilder) AddVersion

func (b *HandshakeRequestBuilder) AddVersion(version string) error

AddVersion accepts the version of the Bayeux protocol that the client supports.

func (*HandshakeRequestBuilder) Build

func (b *HandshakeRequestBuilder) Build() ([]Message, error)

Build generates the final Message to be sent as a Handshake Request

type Message

type Message struct {
	// Advice provides a way for servers to inform clients of their preferred
	// mode of client operation.
	//
	// See also: https://docs.cometd.org/current/reference/#_bayeux_advice
	Advice *Advice `json:"advice,omitempty"`
	// ID represents the identifier of the specific message
	//
	// See also: https://docs.cometd.org/current/reference/#_bayeux_id
	ID string `json:"id,omitempty"`
	// Channel is the Channel on which the message was sent
	//
	// See also: https://docs.cometd.org/current/reference/#_channel
	Channel Channel `json:"channel"`
	// ClientID identifies a particular session via a session id token
	//
	// See also: https://docs.cometd.org/current/reference/#_bayeux_clientid
	ClientID string `json:"clientId,omitempty"`
	// Data contains an event information and optionally could contain
	// a binary representation of the data.
	// There is the MessageData type can be used for binary data
	//
	// See also:
	// https://docs.cometd.org/current/reference/#_data
	// https://docs.cometd.org/current/reference/#_concepts_binary_data
	Data json.RawMessage `json:"data,omitempty"`
	// Version indicates the protocol version expected by the client/server.
	// This MUST be included in messages to/from the `/meta/handshake`
	// channel.
	//
	// See also: https://docs.cometd.org/current/reference/#_version_2
	Version string `json:"version,omitempty"`
	// MinimumVersion indicates the oldest protocol version that can be handled
	// by the client/server. This MAY be included.
	//
	// See also: https://docs.cometd.org/current/reference/#_minimumversion
	MinimumVersion string `json:"minimumVersion,omitempty"`
	// SupportedConnectionTypes is included in messages to/from the
	// `/meta/handshake` channel to allow clients and servers to reveal the
	// transports that are supported. This is an array of strings.
	//
	// See also: https://docs.cometd.org/current/reference/#_bayeux_supported_connections
	SupportedConnectionTypes []string `json:"supportedConnectionTypes,omitempty"`
	// ConnectionType specifies the type of transport the client requires for
	// communication. This MUST be included in `/meta/connect` request
	// messages.
	//
	// See also:
	// https://docs.cometd.org/current/reference/#_connectiontype
	// https://docs.cometd.org/current/reference/#_bayeux_supported_connections
	ConnectionType string `json:"connectionType,omitempty"`
	// Timestamp is an optional field in all Bayeux messages. If present, it
	// SHOULD be specified in the following ISO 8601 profile:
	// `YYYY-MM-DDThh:mm:ss.ss`
	//
	// See also: https://docs.cometd.org/current/reference/#_timestamp
	Timestamp string `json:"timestamp,omitempty"`
	// Successful is a boolean field used to indicate success or failure and
	// MUST be included in responses to `/meta/handshake`, `/meta/connect`,
	// `/meta/subscribe`, `/meta/unsubscribe`, `/meta/disconnect`, and publish
	// channels.
	//
	// See also: https://docs.cometd.org/current/reference/#_successful
	Successful bool `json:"successful,omitempty"`
	// AuthSuccessful is not a common field but MAY be included on a handshake
	// response.
	AuthSuccessful bool `json:"authSuccessful,omitempty"`
	// Subscription specifies the channels the client wishes to subscribe to
	// or unsubscribe from and MUST be included in requests and responses
	// to/from the `/meta/subscribe` or `/meta/unsubscribe` channels.
	//
	// See also: https://docs.cometd.org/current/reference/#_subscription
	Subscription []Channel `json:"subscription,omitempty"`
	// Error field is optional in any response and MAY indicate the type of
	// error that occurred when a request returns with a false successful
	// message.
	//
	// See also: https://docs.cometd.org/current/reference/#_error
	Error string `json:"error,omitempty"`
	// Ext is an optional field that SHOULD be JSON encoded. The contents can
	// be arbitrary values that allow extension sto be negotiated and
	// implemented between server and client implementations.
	//
	// See also: https://docs.cometd.org/current/reference/#_bayeux_ext
	Ext map[string]interface{} `json:"ext,omitempty"`
}

Message represents a message received by a Bayeux client

See also: https://docs.cometd.org/current/reference/#_bayeux_message_fields

func (*Message) GetExt

func (m *Message) GetExt(create bool) map[string]interface{}

GetExt retrieves the Ext field map. If passed `true` it will instantiate it if the map is not instantiated, otherwise it will just return the value of Ext.

func (*Message) ParseError

func (m *Message) ParseError() (MessageError, error)

ParseError returns a struct representing the error message and parsed as defined in the specification.

See also: https://docs.cometd.org/current/reference/#_error

func (*Message) TimestampAsTime

func (m *Message) TimestampAsTime() (time.Time, error)

TimestampAsTime returns the Timestamp in a message as a time.Time struct

type MessageData

type MessageData struct {
	// Data is the actual binary representation of the data
	Data string `json:"data,omitempty"`
	// Last tells whether the `data` field is the last chunk of binary data
	Last bool `json:"last,omitempty"`
	// Meta is an optional field that caries related additional metadata
	Meta map[string]string `json:"meta,omitempty"`
}

MessageData represents the JSON object which contains the binary representation of the data in a Bayeux Message.

See also: https://docs.cometd.org/current/reference/#_concepts_binary_data

type MessageError

type MessageError struct {
	ErrorCode    int
	ErrorArgs    []string
	ErrorMessage string
}

MessageError represents a parsed Error field of a Message

See also: https://docs.cometd.org/current/reference/#_error

type MessageExtender

type MessageExtender interface {
	Outgoing(*Message)
	Incoming(*Message)
	Registered(extensionName string, client *BayeuxClient)
	Unregistered()
}

MessageExtender defines the interface that extensions are expected to implement

type Option

type Option func(*Options)

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithLogger returns an Option with custom http.Client.

func WithHTTPTransport

func WithHTTPTransport(transport *http.Transport) Option

WithLogger returns an Option with custom http.Transport.

func WithLogger

func WithLogger(logger logrus.FieldLogger) Option

WithLogger returns an Option with logger.

type Options

type Options struct {
	Logger    logrus.FieldLogger
	Client    *http.Client
	Transport *http.Transport
}

type StateRepresentation

type StateRepresentation string

StateRepresentation represents the current state of a connection as a string

type SubscribeRequestBuilder

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

SubscribeRequestBuilder provides an easy way to build a /meta/subscribe request per the specification in https://docs.cometd.org/current/reference/#_subscribe_request

Example
b := NewSubscribeRequestBuilder()
if err := b.AddSubscription("/foo/**"); err != nil {
	return
}
if err := b.AddSubscription("/foo/**"); err != nil { // NOTE We de-duplicate channels
	return
}
if err := b.AddSubscription("/bar/foo"); err != nil {
	return
}
b.AddClientID("Un1q31d3nt1f13r")
m, err := b.Build()
if err != nil {
	return
}
jsonBytes, err := json.Marshal(m)
if err != nil {
	return
}
fmt.Println(string(jsonBytes))
Output:

[{"channel":"/meta/subscribe","clientId":"Un1q31d3nt1f13r","subscription":["/foo/**","/bar/foo"]}]

func NewSubscribeRequestBuilder

func NewSubscribeRequestBuilder() *SubscribeRequestBuilder

NewSubscribeRequestBuilder initializes a SubscribeRequestBuilder as an easy way to build a Message that can be sent as a /meta/subscribe request. See also https://docs.cometd.org/current/reference/#_subscribe_request

func (*SubscribeRequestBuilder) AddClientID

func (b *SubscribeRequestBuilder) AddClientID(clientID string)

AddClientID adds the previously provided clientId to the request

func (*SubscribeRequestBuilder) AddSubscription

func (b *SubscribeRequestBuilder) AddSubscription(c Channel) error

AddSubscription adds a given channel to the list of subscriptions being sent in a /meta/subscribe request

func (*SubscribeRequestBuilder) Build

func (b *SubscribeRequestBuilder) Build() ([]Message, error)

Build generates the final Message to be sent as a Subscribe Request

type UnsubscribeRequestBuilder

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

UnsubscribeRequestBuilder provides an easy way to build a /meta/unsubscribe request per the specification in https://docs.cometd.org/current/reference/#_unsubscribe_request

Example
b := NewUnsubscribeRequestBuilder()
if err := b.AddSubscription("/foo/**"); err != nil {
	return
}
if err := b.AddSubscription("/foo/**"); err != nil { // NOTE We de-duplicate channels
	return
}
if err := b.AddSubscription("/bar/foo"); err != nil {
	return
}
b.AddClientID("Un1q31d3nt1f13r")
m, err := b.Build()
if err != nil {
	return
}
jsonBytes, err := json.Marshal(m)
if err != nil {
	return
}
fmt.Println(string(jsonBytes))
Output:

[{"channel":"/meta/unsubscribe","clientId":"Un1q31d3nt1f13r","subscription":["/foo/**","/bar/foo"]}]

func NewUnsubscribeRequestBuilder

func NewUnsubscribeRequestBuilder() *UnsubscribeRequestBuilder

NewUnsubscribeRequestBuilder initializes a SubscribeRequestBuilder as an easy way to build a Message that can be sent as a /meta/subscribe request. See also https://docs.cometd.org/current/reference/#_unsubscribe_request

func (*UnsubscribeRequestBuilder) AddClientID

func (b *UnsubscribeRequestBuilder) AddClientID(clientID string)

AddClientID adds the previously provided clientId to the request

func (*UnsubscribeRequestBuilder) AddSubscription

func (b *UnsubscribeRequestBuilder) AddSubscription(c Channel) error

AddSubscription adds a given channel to the list of subscriptions being sent in a /meta/unsubscribe request

func (*UnsubscribeRequestBuilder) Build

func (b *UnsubscribeRequestBuilder) Build() ([]Message, error)

Build generates the final Message to be sent as a Unsubscribe Request

Directories

Path Synopsis
cmd
t
extensions

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL