websocket

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2026 License: BSD-3-Clause Imports: 22 Imported by: 0

Documentation

Overview

Package websocket can connect to a WebSocket server from within a CLI app.

Index

Constants

View Source
const (
	// TextMessage denotes a text data message, whose payload is interpreted as
	// UTF-8 encoded text
	TextMessage = MessageType(ws.TextMessage)

	// BinaryMessage denotes a binary data message
	BinaryMessage = MessageType(ws.BinaryMessage)
)

Variables

View Source
var (
	// ErrNoLocation is reported when no URL has been specified for the client
	ErrNoLocation = errors.New("no WebSocket URL specified")
)

Functions

func Do

func Do(ctx context.Context) error

Do connects the context client and exchanges its messages

func SourceAnnotation

func SourceAnnotation() (string, string)

SourceAnnotation gets the name and value of the annotation added to the Data of all flags that are initialized from this package

Types

type Action

type Action = cli.Action

Action is an alias for the action within the Joe framework

func ConnectAndPrint

func ConnectAndPrint() Action

ConnectAndPrint provides an action which connects to the WebSocket server, sends each of the messages which have been configured, and prints each message which is received.

func ContextValue

func ContextValue(c *Client) Action

ContextValue provides an action which stores the client in the context

func FlagsAndArgs

func FlagsAndArgs() Action

FlagsAndArgs adds the flags and args that can be used to configure the client in the context.

func SetBinary

func SetBinary() Action

SetBinary causes messages to be sent as binary messages

func SetCloseTimeout

func SetCloseTimeout(d ...time.Duration) Action

SetCloseTimeout sets the maximum duration to allow for the closing handshake, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetCompression

func SetCompression(v ...bool) Action

SetCompression enables negotiation of per-message compression

func SetHandshakeTimeout

func SetHandshakeTimeout(d ...time.Duration) Action

SetHandshakeTimeout sets the maximum duration to allow the handshake to complete, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetHeader

func SetHeader(v ...*httpclient.HeaderValue) Action

SetHeader adds a header to the handshake request, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetInput

func SetInput(v ...*cli.FileSet) Action

SetInput sets the files which provide the messages to send, one message per line, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetMessage

func SetMessage(v ...string) Action

SetMessage adds a message which is sent once the connection is established, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetMessageType

func SetMessageType(v ...MessageType) Action

SetMessageType sets the type of the messages which are sent, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetOrigin

func SetOrigin(v ...string) Action

SetOrigin sets the Origin header used in the handshake request, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetReadBufferSize

func SetReadBufferSize(v ...int) Action

SetReadBufferSize sets the size of the read buffer in bytes

func SetReadLimit

func SetReadLimit(v ...int64) Action

SetReadLimit sets the maximum size in bytes of the messages which can be received

func SetReadTimeout

func SetReadTimeout(d ...time.Duration) Action

SetReadTimeout sets the maximum duration to wait for each message which is received, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetSubprotocol

func SetSubprotocol(v ...string) Action

SetSubprotocol adds a subprotocol which is requested during the handshake, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetURLValue

func SetURLValue(u ...*URLValue) Action

SetURLValue sets the location that the client connects to, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

func SetVerbose

func SetVerbose() Action

SetVerbose causes the messages which are sent to be echoed to stderr

func SetWriteBufferSize

func SetWriteBufferSize(v ...int) Action

SetWriteBufferSize sets the size of the write buffer in bytes

func SetWriteTimeout

func SetWriteTimeout(d ...time.Duration) Action

SetWriteTimeout sets the maximum duration to allow for writing each message, which either uses the specified value or reads from the corresponding flag/arg to get the value to set.

type Client

type Client struct {
	cli.Action
	// contains filtered or unexported fields
}

Client provides a WebSocket client (which encapsulates a websocket.Dialer) that can be accessed from commands, flags, and args within Joe applications. The client is used within the Uses pipeline where it registers itself as a context service together with the flags and args that configure it. The action ConnectAndPrint is used to actually exchange messages:

&cli.App{
   Name: "gows",
   Uses: websocket.New(),
   Action: websocket.ConnectAndPrint(),
}

This simple app has numerous flags to configure the handshake and message handling, and its simplest invocation could be something like

gows ws://example.com/graphql

The client is configured exclusively with Options, either passed to New or applied later using Apply. The underlying websocket.Dialer is created on demand the first time it is needed, which is available from NewDialer. How it gets created can be customized with WithDialer or WithDialerFactory.

The cmd/mop package provides mop, which is a command line utility very similar to this.

If you only want to add the Client to the context (typically in advanced scenarios where you are deeply customizing the behavior), you only use the action websocket.ContextValue() with the client you want to add instead of add the client to the pipeline directly.

func FromContext

func FromContext(ctx context.Context) *Client

FromContext obtains the client stored in the context

func New

func New(options ...Option) *Client

New creates a new WebSocket client with the given options.

func (*Client) Apply

func (c *Client) Apply(opts ...Option)

Apply applies the given options to the client

func (*Client) Dial

func (c *Client) Dial(ctx context.Context) (*Conn, error)

Dial establishes the connection to the location which has been configured

func (*Client) Do

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

Do establishes the connection, sends each message which has been configured, and then copies each message which is received to the output until the peer closes the connection or the read timeout elapses.

func (*Client) Location

func (c *Client) Location() (*URLValue, error)

Location obtains the URL that the client connects to

func (*Client) NewDialer

func (c *Client) NewDialer(ctx context.Context) (*ws.Dialer, error)

NewDialer creates (or returns the cached) websocket.Dialer for the client

func (*Client) NewTLSConfig

func (c *Client) NewTLSConfig(ctx context.Context) (*gotls.Config, error)

NewTLSConfig creates the TLS config

func (*Client) Pipeline

func (c *Client) Pipeline() cli.Action

Pipeline obtains the action that the client contributes to the app

type Conn

type Conn struct {
	*ws.Conn
	// contains filtered or unexported fields
}

Conn represents a WebSocket connection which has been established by the client. It wraps the underlying websocket.Conn so that the timeouts and message type which were configured on the client are applied to each operation. The embedded connection can be used directly when more control is required.

func (*Conn) CloseNormal

func (c *Conn) CloseNormal() error

CloseNormal performs the closing handshake, indicating normal closure

func (*Conn) Receive

func (c *Conn) Receive() (MessageType, []byte, error)

Receive reads the next message from the connection

func (*Conn) Response

func (c *Conn) Response() *http.Response

Response obtains the HTTP response from the handshake

func (*Conn) Send

func (c *Conn) Send(data []byte) error

Send writes the message using the message type which was configured on the client

type MessageType

type MessageType int

MessageType identifies the type of a WebSocket message

func (MessageType) MarshalText

func (m MessageType) MarshalText() ([]byte, error)

MarshalText provides the textual representation of the message type

func (*MessageType) Set

func (m *MessageType) Set(arg string) error

Set updates the value from the text of the flag or arg

func (MessageType) String

func (m MessageType) String() string

String obtains the name of the message type

func (MessageType) Synopsis

func (MessageType) Synopsis() string

Synopsis obtains the placeholder text used in help screens

func (*MessageType) UnmarshalText

func (m *MessageType) UnmarshalText(b []byte) error

UnmarshalText parses the textual representation of the message type

type Option

type Option interface {
	cli.Action
	// contains filtered or unexported methods
}

Option is an option to configure the client. Option can be used as an Action, typically within the Uses or Before pipeline.

func WithAction

func WithAction(a cli.Action) Option

WithAction sets the action

func WithCloseTimeout

func WithCloseTimeout(d time.Duration) Option

WithCloseTimeout sets the amount of time to allow for the closing handshake

func WithCompression

func WithCompression(v bool) Option

WithCompression enables negotiation of per-message compression

func WithDefaultAction

func WithDefaultAction() Option

WithDefaultAction sets the action to the default, which registers the client in the context along with the flags and args that configure it.

func WithDefaultDialerFactory

func WithDefaultDialerFactory() Option

WithDefaultDialerFactory sets up the default dialer factory and the built-in dialer middleware (connection settings and TLS setup). This option is applied automatically by New.

func WithDefaultTLSConfigFactory

func WithDefaultTLSConfigFactory() Option

WithDefaultTLSConfigFactory provides the default factory, which provides TLS from the context

func WithDialer

func WithDialer(d *ws.Dialer) Option

WithDialer sets the websocket.Dialer to use directly, bypassing the default factory. The connection settings which have been configured with the other options are still applied to it.

func WithDialerFactory

func WithDialerFactory(fn func(context.Context) (*ws.Dialer, error)) Option

WithDialerFactory provides a factory for obtaining the websocket.Dialer.

func WithHandshakeTimeout

func WithHandshakeTimeout(d time.Duration) Option

WithHandshakeTimeout sets the amount of time to allow the handshake to complete

func WithHeader

func WithHeader(name, value string) Option

WithHeader adds a header to the handshake request. Note that the Sec-WebSocket-Protocol header is set from the subprotocols which have been configured with WithSubprotocol rather than being set directly.

func WithInput

func WithInput(files *cli.FileSet) Option

WithInput sets the files that provide the messages to send, one message per line. When the file set is empty, standard input is used unless it is a terminal.

func WithMessage

func WithMessage(text string) Option

WithMessage adds a message which is sent once the connection is established. Messages are sent before any which are read from the input.

func WithMessageType

func WithMessageType(m MessageType) Option

WithMessageType sets the type of the messages which are sent

func WithOrigin

func WithOrigin(origin string) Option

WithOrigin sets the Origin header used in the handshake request

func WithReadBufferSize

func WithReadBufferSize(n int) Option

WithReadBufferSize sets the size of the read buffer in bytes

func WithReadLimit

func WithReadLimit(n int64) Option

WithReadLimit sets the maximum size in bytes of the messages which can be received

func WithReadTimeout

func WithReadTimeout(d time.Duration) Option

WithReadTimeout sets the amount of time to wait for each message which is received. When the timeout elapses, the exchange has ended.

func WithSubprotocol

func WithSubprotocol(name string) Option

WithSubprotocol adds a subprotocol which is requested during the handshake

func WithTLSConfig

func WithTLSConfig(t *gotls.Config) Option

WithTLSConfig sets the TLS config for use on the client

func WithTLSConfigFactory

func WithTLSConfigFactory(fn func(context.Context) (*gotls.Config, error)) Option

WithTLSConfigFactory provides a factory for obtaining TLS config

func WithURL

func WithURL(loc string) Option

WithURL sets the location that the client connects to. The text is interpreted as described by URLValue.

func WithVerbose

func WithVerbose(v bool) Option

WithVerbose causes the messages which are sent to be echoed to stderr

func WithWriteBufferSize

func WithWriteBufferSize(n int) Option

WithWriteBufferSize sets the size of the write buffer in bytes

func WithWriteTimeout

func WithWriteTimeout(d time.Duration) Option

WithWriteTimeout sets the amount of time to allow for writing each message

type Options

type Options struct {
	URL              *string           `toml:"url"                json:"url,omitempty"`
	Headers          map[string]string `toml:"headers"            json:"headers,omitempty"`
	Origin           *string           `toml:"origin"             json:"origin,omitempty"`
	Subprotocols     []string          `toml:"subprotocols"       json:"subprotocols,omitempty"`
	Messages         []string          `toml:"messages"           json:"messages,omitempty"`
	MessageType      *MessageType      `toml:"message-type"       json:"messageType,omitempty"`
	HandshakeTimeout *time.Duration    `toml:"handshake-timeout"  json:"handshakeTimeout,omitempty"`
	ReadTimeout      *time.Duration    `toml:"read-timeout"       json:"readTimeout,omitempty"`
	WriteTimeout     *time.Duration    `toml:"write-timeout"      json:"writeTimeout,omitempty"`
	CloseTimeout     *time.Duration    `toml:"close-timeout"      json:"closeTimeout,omitempty"`
	ReadBufferSize   *int              `toml:"read-buffer-size"   json:"readBufferSize,omitempty"`
	WriteBufferSize  *int              `toml:"write-buffer-size"  json:"writeBufferSize,omitempty"`
	ReadLimit        *int64            `toml:"read-limit"         json:"readLimit,omitempty"`
	Compression      *bool             `toml:"compression"        json:"compression,omitempty"`
	Verbose          *bool             `toml:"verbose"            json:"verbose,omitempty"`
}

Options contains settings for the client which have data representations. Each non-nil field is applied when Options is used as an Option.

func (*Options) Execute

func (o *Options) Execute(ctx context.Context) error

Execute applies the options to the client in the context

type URLValue

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

URLValue provides ergonomics for entering WebSocket URLs as values. When the text looks like a port (e.g. :8080), the URL is interpreted as localhost. When the text looks like a hostname, the prefix ws:// is prepended. The HTTP schemes are converted to their WebSocket counterparts, so that http becomes ws and https becomes wss.

func NewURLValue

func NewURLValue(loc string) *URLValue

NewURLValue creates a new URLValue from a string

func (*URLValue) Copy

func (u *URLValue) Copy() *URLValue

Copy duplicates the value

func (*URLValue) Reset

func (u *URLValue) Reset()

Reset clears the value, which facilitates its re-use

func (*URLValue) Set

func (u *URLValue) Set(arg string) error

Set updates the value from the text of the flag or arg

func (*URLValue) String

func (u *URLValue) String() string

String obtains the text of the value

func (*URLValue) URL

func (u *URLValue) URL() (*url.URL, error)

URL interprets the value as a URL

Jump to

Keyboard shortcuts

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