gobayeux

package module
v2.5.0 Latest Latest
Warning

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

Go to latest
Published: Dec 8, 2023 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package gobayeux provides both a low-level protocol client and a higher-level client that improves the ergonomics of talking to a server implementing the Bayeux Protocol.

The best way to create a high-level client is with `NewClient`. Provided a server address for the server you're using, you can create a client like so

serverAddress := "https://localhost:8080/"
client := gobayeux.NewClient(serverAddress)

You can also register customer HTTP transports with your client

	transport := &http.Transport{
		DialContext: (&net.Dialer{
  			Timeout:   3 * time.Second,
  			KeepAlive: 10 * time.Second,
  		}).DialContext,
	}
	client := gobayeux.NewClient(serverAddress, gobayeux.WithHTTPTransport(transport))

You can subscribe to a Bayeux Channel with a chan to receive messages on

recv := make(chan []gobayeux.Message)
client.Subscribe("example-channel", recv)

You can also register extensions that you'd like to use with the server by implementing the MessageExtender interface and then passing it to the client

	type Example struct {}
	func (e *Example) Registered(name string, client *gobayeux.BayeuxClient) {}
	func (e *Example) Unregistered() {}
	func (e *Example) Outgoing(m *gobayeux.Message) {
   		switch m.Channel {
   		case gobayeux.MetaHandshake:
   			ext := m.GetExt(true)
   			ext["example"] = true
		}
	}
	func (e *Example) Incoming(m *gobayeux.Message) {}

	var _ gobayeux.MessageExtender = (*Example)(nil)

	e := &Example{}
	client.UseExtension(e)

Index

Examples

Constants

View Source
const (
	// ErrClientNotConnected is returned when the client is not connected
	ErrClientNotConnected = sentinel("client not connected to server")

	// ErrTooManyMessages is returned when there is more than one handshake message
	ErrTooManyMessages = sentinel("more messages than expected in handshake response")

	// ErrBadChannel is returned when the handshake response is on the wrong channel
	ErrBadChannel = sentinel("handshake responses must come back via the /meta/handshake channel")

	// ErrFailedToConnect is a general connection error
	ErrFailedToConnect = sentinel("connect request was not successful")

	// ErrNoSupportedConnectionTypes is returned when the client and server
	// aren't able to agree on a connection type
	ErrNoSupportedConnectionTypes = sentinel("no supported connection types provided")

	// ErrNoVersion is returned when a version is not provided
	ErrNoVersion = sentinel("no version specified")

	// ErrMissingClientID is returned when the client id has not been set
	ErrMissingClientID = sentinel("missing clientID value")

	// ErrMissingConnectionType is returned when the connection type is unset
	ErrMissingConnectionType = sentinel("missing connectionType value")
)
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 ActionFailedError

type ActionFailedError struct {
	Action       string
	ErrorMessage string
}

ActionFailedError is a general purpose error returned by the BayeuxClient

func (ActionFailedError) Error

func (e ActionFailedError) Error() string

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 AlreadyRegisteredError

type AlreadyRegisteredError struct {
	MessageExtender
}

AlreadyRegisteredError signifies that the given MessageExtender is already registered with the client

func (AlreadyRegisteredError) Error

func (e AlreadyRegisteredError) Error() string

type BadConnectionError

type BadConnectionError struct {
	*BadStateError
}

BadConnectionError is returned when trying to connected but not connecting

type BadConnectionTypeError

type BadConnectionTypeError struct {
	ConnectionType string
}

BadConnectionTypeError is returned when we don't know how to handle the requested connection type

func (BadConnectionTypeError) Error

func (e BadConnectionTypeError) Error() string

type BadConnectionVersionError

type BadConnectionVersionError struct {
	Version string
}

BadConnectionVersionError is returned when we can't support the requested version number

func (BadConnectionVersionError) Error

type BadHandshakeError

type BadHandshakeError struct {
	*BadStateError
}

BadHandshakeError is returned when trying to handshake but not unconnected

type BadResponseError

type BadResponseError struct {
	StatusCode int
	Status     string
	Body       []byte
}

BadResponseError is returned when we get an unexpected HTTP response from the server

func (BadResponseError) Error

func (e BadResponseError) Error() string

type BadStateError

type BadStateError struct {
	CurrentState int32
	FromState    int32
	ToState      int32
	Message      string
}

BadStateError is returned when the state machine transition is not valid

func (BadStateError) Error

func (e BadStateError) Error() string

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.RoundTripper, serverAddress string, logger Logger) (*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

func (*BayeuxClient) UseExtension

func (b *BayeuxClient) UseExtension(ext MessageExtender) error

UseExtension adds the provided MessageExtender to the list of known extensions

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

func (*Client) Unsubscribe added in v2.5.0

func (c *Client) Unsubscribe(ch Channel)

Unsubscribe queues a request to unsubscribe from a channel on the server

func (*Client) UseExtension

func (c *Client) UseExtension(ext MessageExtender) error

UseExtension adds the provided MessageExtender as an extension for use with this Client session.

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

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 ConnectionFailedError

type ConnectionFailedError struct {
	Err error
}

ConnectionFailedError is returned whenever Connect is called and it fails

func (ConnectionFailedError) Error

func (e ConnectionFailedError) Error() string

func (ConnectionFailedError) Unwrap

func (e ConnectionFailedError) Unwrap() error

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 DisconnectFailedError

type DisconnectFailedError struct {
	Err error
}

DisconnectFailedError is returned when the call to Disconnect fails

func (DisconnectFailedError) Error

func (e DisconnectFailedError) Error() string

func (DisconnectFailedError) Unwrap

func (e DisconnectFailedError) Unwrap() error

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 EmptySliceError

type EmptySliceError string

EmptySliceError is returned when an empty slice is unexpected

func (EmptySliceError) Error

func (e EmptySliceError) Error() string

type ErrMessageUnparsable

type ErrMessageUnparsable string

ErrMessageUnparsable is returned when we fail to parse a message

func (ErrMessageUnparsable) Error

func (e ErrMessageUnparsable) Error() string

type Event

type Event string

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

type HandshakeFailedError

type HandshakeFailedError struct {
	Err error
}

HandshakeFailedError is returned whenever the handshake fails

func (HandshakeFailedError) Error

func (e HandshakeFailedError) Error() string

func (HandshakeFailedError) Unwrap

func (e HandshakeFailedError) Unwrap() error

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 IgnoreErrorFunc added in v2.4.0

type IgnoreErrorFunc func(error) bool

IgnoreErrorFunc is a callback function that inspects an error and determines if it can be safely ignored when subscribing and unsubscribing.

type InvalidChannelError

type InvalidChannelError struct {
	Channel
}

InvalidChannelError is the result of a failure to validate a channel name

func (InvalidChannelError) Error

func (e InvalidChannelError) Error() string

type Logger added in v2.3.0

type Logger interface {
	// Debug takes a message and any number of arguments and logs them at the
	// debug level
	Debug(msg string, args ...any)

	// Info takes a message and any number of arguments and logs them at the
	// info level
	Info(msg string, args ...any)

	// Warn takes a message and any number of arguments and logs them at the
	// warn level
	Warn(msg string, args ...any)

	// Error takes a message and any number of arguments and logs them at the
	// error level
	Error(msg string, args ...any)

	// WithError returns a new Logger that addes the given error to any log
	// messages emitted
	WithError(error) Logger

	// WithField returns a new Logger that adds the given key/value to any
	// log messages emitted
	WithField(key string, value any) Logger
}

Logger defines the logging interface gobayeux leverages

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

Option defines the type passed into NewClient for configuration

func WithFieldLogger added in v2.3.0

func WithFieldLogger(logger logrus.FieldLogger) Option

WithFieldLogger returns an Option with logger.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient returns an Option with custom http.Client.

func WithHTTPTransport

func WithHTTPTransport(transport http.RoundTripper) Option

WithHTTPTransport returns an Option with custom http.RoundTripper.

func WithIgnoreError added in v2.4.0

func WithIgnoreError(f IgnoreErrorFunc) Option

WithIgnoreError takes a function that will be called whenever an error is returned while subscribing or unsubscribing. If the function returns true, the error will not be considered fatal the the event loop will continue.

The default is to stop when an error is received.

func WithLogger

func WithLogger(logger Logger) Option

WithLogger returns an Option with logger.

func WithSlogLogger added in v2.3.0

func WithSlogLogger(logger *slog.Logger) Option
Example
//go:build go1.21
// +build go1.21

package main

import (
	"context"
	"log/slog"
	"net/http"
	"os"

	"github.com/sigmavirus24/gobayeux/v2"
)

type roundTripFn func(*http.Request) (*http.Response, error)

func (fn roundTripFn) RoundTrip(r *http.Request) (*http.Response, error) {
	return fn(r)
}

func main() {
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
		Level: slog.LevelDebug,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			if a.Key == slog.TimeKey {
				return slog.Attr{}
			}

			return a
		},
	}))

	handler := roundTripFn(func(r *http.Request) (*http.Response, error) {
		return &http.Response{
			StatusCode: http.StatusOK,
			Status:     http.StatusText(http.StatusOK),
		}, nil
	})

	client, err := gobayeux.NewClient("http://127.0.0.1:9876",
		gobayeux.WithSlogLogger(logger),
		gobayeux.WithHTTPTransport(handler),
	)
	if err != nil {
		panic(err)
	}

	errs := client.Start(context.Background())
	err = <-errs
	if err == nil {
		panic("expected an error when connecting")
	}
}
Output:

level=DEBUG msg=starting at=handshake
level=DEBUG msg="error parsing response" at=handshake error=EOF

type Options

type Options struct {
	Logger      Logger
	Client      *http.Client
	Transport   http.RoundTripper
	IgnoreError IgnoreErrorFunc
}

Options stores the available configuration options for a Client

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/**"},{"channel":"/meta/subscribe","clientId":"Un1q31d3nt1f13r","subscription":"/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 SubscriptionFailedError

type SubscriptionFailedError struct {
	Channels []Channel
	Err      error
}

SubscriptionFailedError is returned for any errors on Subscribe

func (SubscriptionFailedError) Error

func (e SubscriptionFailedError) Error() string

func (SubscriptionFailedError) Unwrap

func (e SubscriptionFailedError) Unwrap() error

type UnknownEventTypeError

type UnknownEventTypeError struct {
	Event
}

UnknownEventTypeError is returned when the next state is unknown

func (UnknownEventTypeError) Error

func (e UnknownEventTypeError) Error() string

type UnsubscribeFailedError

type UnsubscribeFailedError struct {
	Channels []Channel
	Err      error
}

UnsubscribeFailedError is returned for any errors on Unsubscribe

func (UnsubscribeFailedError) Error

func (e UnsubscribeFailedError) Error() string

func (UnsubscribeFailedError) Unwrap

func (e UnsubscribeFailedError) Unwrap() error

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/**"},{"channel":"/meta/unsubscribe","clientId":"Un1q31d3nt1f13r","subscription":"/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
extensions
replay
Package replay provides an interface and in-memory implementation of the replay ID extension for the Bayeux protocol.
Package replay provides an interface and in-memory implementation of the replay ID extension for the Bayeux protocol.
salesforce
Package salesforce provides a simple way of authenticating with Salesforce.com Bayeux-powered services.
Package salesforce provides a simple way of authenticating with Salesforce.com Bayeux-powered services.
internal

Jump to

Keyboard shortcuts

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