Documentation ¶
Index ¶
- Constants
- func EncodeConvey(convey Convey, encoding *base64.Encoding) (string, error)
- func IDHashParser(deviceNameHeader string) func(*http.Request) ([]byte, error)
- func NewConnectHandler(manager Manager, responseHeader http.Header, logger logging.Logger) http.Handler
- func NewDeviceListHandler(manager Manager, logger logging.Logger) http.Handler
- type ConnectListener
- type Connection
- type ConnectionFactory
- type Convey
- type DeviceError
- type Dialer
- type DisconnectListener
- type ID
- type Interface
- type Key
- type KeyFunc
- type Manager
- type MessageListener
- type Options
- type PongListener
Constants ¶
const ( DefaultDeviceNameHeader = "X-Webpa-Device-Name" DefaultConveyHeader = "X-Webpa-Convey" DefaultHandshakeTimeout time.Duration = 10 * time.Second DefaultIdlePeriod time.Duration = 135 * time.Second DefaultWriteTimeout time.Duration = 60 * time.Second DefaultPingPeriod time.Duration = 45 * time.Second DefaultInitialCapacity = 100000 DefaultReadBufferSize = 4096 DefaultWriteBufferSize = 4096 DefaultDeviceMessageQueueSize = 100 )
const ( // DeviceManagerKey is the Viper subkey under which device.Options are typically stored // In a JSON configuration file, this will be expressed as: // // { // /* other stuff can be here */ // // "device": { // "manager": { // } // } // } DeviceManagerKey = "device.manager" )
Variables ¶
This section is empty.
Functions ¶
func EncodeConvey ¶
EncodeConvey transforms a Convey map into its on-the-wire representation, using the supplied encoding. If encoding == nil, base64.StdEncoding is used.
func IDHashParser ¶
IDHashParser creates a parsing function that examines an HTTP request to produce a []byte key for consistent hashing. The returned function examines the given request header and invokes ParseID on the value.
If deviceNameHeader is the empty string, DefaultDeviceNameHeader is used.
Types ¶
type ConnectListener ¶
type ConnectListener func(Interface)
ConnectListener is a function which receives notifications when devices successfully connect to the system.
func ConnectListeners ¶
func ConnectListeners(listeners ...ConnectListener) ConnectListener
ConnectListeners aggregates multiple listeners into one. If this method is passed zero (0) listeners, an internal default is used instead.
type Connection ¶
type Connection interface { io.Closer // Read returns the next WRP message frame. If this method returns an error, // this connection should be abandoned and closed. This method is not safe // for concurrent invocation and must not be invoked concurrently with Write(). // // Both the raw data frame (a byte slice) and the decoded message are returned. This // allows for efficient transfers, since calling code can choose to simply hand the byte // slice off rather than re-encoding the message. // // Read may skip frames if they are not supported by the WRP protocol. For example, // text frames are not supported and are skipped. Anytime a frame is skipped, this // method returns a nil message with a nil error. Read() ([]byte, *wrp.Message, error) // Write sends a WRP frame to the device. If this method returns an error, // this connection should be abandoned and closed. This method is not safe // for concurrent invocation and must not be invoked concurrently with Read(). Write(*wrp.Message) error // Ping sends a ping message to the device. This method may be invoked concurrently // with any other method of this interface, including Ping() itself. Ping([]byte) error // SetPongCallback registers the given function to be invoked whenever this connection // notices a pong from the device. Note that this is not the same as a handler. This callback // cannot return an error, and is invoked as part of the internal pong handler that // enforces the idle policy. The pong callback can be nil, which simply reverts back // to the internal default handler. // // This method cannot be called concurrently with Write(). SetPongCallback(func(string)) // SendClose transmits a close frame to the device. After this method is invoked, // the only method that should be invoked is Close() SendClose() error }
Connection represents a websocket connection to a WebPA-compatible device. Connection implementations abstract the semantics of serverside WRP message handling and enforce policies like idleness.
type ConnectionFactory ¶
type ConnectionFactory interface {
NewConnection(http.ResponseWriter, *http.Request, http.Header) (Connection, error)
}
ConnectionFactory provides the instantiation logic for Connections. This interface is appropriate for server-side connections that enforce various WebPA policies, such as idleness and a write timeout.
func NewConnectionFactory ¶
func NewConnectionFactory(o *Options) ConnectionFactory
NewConnectionFactory produces a ConnectionFactory instance from a set of Options.
type Convey ¶
type Convey map[string]interface{}
Convey represents an arbitrary block of JSON that should be transmitted in HTTP requests related to devices. It is typically sent via a header as base64-encoded JSON.
type DeviceError ¶
DeviceError is the common interface implemented by all error objects which carry device-related metadata
func NewBusyError ¶
func NewBusyError(id ID, key Key) DeviceError
func NewClosedError ¶
func NewClosedError(id ID, key Key) DeviceError
func NewDuplicateKeyError ¶
func NewDuplicateKeyError(key Key) DeviceError
func NewMissingIDError ¶
func NewMissingIDError(id ID) DeviceError
func NewMissingKeyError ¶
func NewMissingKeyError(key Key) DeviceError
type Dialer ¶
type Dialer interface {
Dial(URL string, id ID, convey Convey, extra http.Header) (Connection, *http.Response, error)
}
Dialer is a WebPA dialer for websocket Connections
func NewDialer ¶
NewDialer constructs a WebPA Dialer using a set of Options and a gorilla Dialer. Both parameters are optional. If the gorilla Dialer is supplied, it is copied for use internally. If an Options is supplied, the appropriate settings will override any gorilla Dialer, e.g. ReadBufferSize.
type DisconnectListener ¶
type DisconnectListener func(Interface)
DisconnectListener is a function which receives notifications when devices disconnect (or, are disconnected) from the system
func DisconnectListeners ¶
func DisconnectListeners(listeners ...DisconnectListener) DisconnectListener
DisconnectListeners aggregates multiple listeners into one. If this method is passed zero (0) listeners, an internal default is used instead.
type ID ¶
type ID string
ID represents a normalized identifer for a device.
func IntToMAC ¶
IntToMAC accepts a 64-bit integer and formats that as a device MAC address identifier The returned ID will be of the form mac:XXXXXXXXXXXX, where X is a hexadecimal digit using lowercased letters.
type Interface ¶
type Interface interface { // ID returns the canonicalized identifer for this device. Note that // this is NOT globally unique. It is possible for multiple devices // with the same ID to be connected. This typically occurs due to fraud, // but we don't want to turn away duped devices. ID() ID // Key returns the current unique key for this device. Key() Key // Convey returns the payload to convey with each web-bound request Convey() Convey // ConnectedAt returns the time at which this device connected to the system ConnectedAt() time.Time // RequestClose posts a request for this device to be disconnected. This method // is asynchronous and idempotent. If this method is invoked when a shutdown // request has already been queued or when this device is already shut down, this // method returns an error. RequestClose() // Closed tests if this device is closed. When this method returns true, // any attempt to send messages to this device will result in an error. // // Once closed, a device cannot be reopened. Closed() bool // Send dispatches a message to this device. This method is useful outside // a Manager if multiple messages should be sent to the device. // // This method will return an error if this device has been closed or // if the device is busy and cannot accept more messages. Send(*wrp.Message) error }
Interface is the core type for this package. It provides access to public device metadata and the ability to send messages directly the a device.
Instances are mostly immutable, and have a strict lifecycle. Devices are initially open, and when closed cannot be reused or reopened. A new device instance is required if further communication is desired after the original device instance is closed.
The only piece of metadata that is mutable is the Key. A device Manager allows clients to change the routing Key of a device. All other public metadata is immutable.
type Key ¶
type Key string
Key is a routing identifier for a device. While multiple devices in a Manager can have the same ID, Keys are unique to specific devices.
type Manager ¶
type Manager interface { // Connect upgrade an HTTP connection to a websocket and begins concurrent // managment of the device. Connect(http.ResponseWriter, *http.Request, http.Header) (Interface, error) // Disconnect disconnects all devices (including duplicates) which connected // with the given ID. This method returns the number of devices disconnected, // which can be zero or a positive integer. Multiple devices are permitted with // the same ID, and this method disconnects all duplicate devices associated with that ID. Disconnect(ID) int // DisconnectOne disconnects the single device associated with the given Key. This method // returns the count of devices disconnected, which will be zero (0) if no device existed // or one (1) if there was a device with that key. DisconnectOne(Key) int // DisconnectIf iterates over all devices known to this manager, applying the // given predicate. For any devices that result in true, this method disconnects them. // Note that this method may pause connections and disconnections while it is executing. // This method returns the number of devices that were disconnected. // // Only disconnection by ID is supported, which means that any identifier matching // the predicate will result in *all* duplicate devices under that ID being removed. // // No methods on this Manager should be called from within the predicate function, or // a deadlock will likely occur. DisconnectIf(func(ID) bool) int // VisitIf applies a visitor to any device matching the ID predicate. // // No methods on this Manager should be called from within either the predicate // or the visitor, or a deadlock will most definitely occur. VisitIf(func(ID) bool, func(Interface)) int // VisitAll applies the given visitor function to each device known to this manager. // // No methods on this Manager should be called from within the visitor function, or // a deadlock will likely occur. VisitAll(func(Interface)) int // Send dispatches a message to all devices registered with the given canonical ID. // An optional callback can be supplied to allow the caller to receive information // for each send attempt. This callback will be invoked for each send, successes // being indicated by a nil error. // // No methods on this Manager should be called from within the callback function, or // a deadlock will likely occur. Send(ID, *wrp.Message, func(Interface, error)) error // SendOne attempts to send a message to the single, unique device identified by the Key. SendOne(Key, *wrp.Message) error }
Manager supplies a hub for connecting and disconnecting devices as well as an access point for obtaining device metadata.
func NewManager ¶
func NewManager(o *Options, cf ConnectionFactory) Manager
NewManager constructs a Manager from a set of options. A ConnectionFactory will be created from the options if one is not supplied.
type MessageListener ¶
MessageListener represents a sink for device messages
func MessageListeners ¶
func MessageListeners(listeners ...MessageListener) MessageListener
MessageListeners aggregates multiple listeners into one. If this method is passed zero (0) listeners, an internal default is used instead.
type Options ¶
type Options struct { // DeviceNameHeader is the name of the HTTP request header which contains the // device name. If not specified, DefaultDeviceNameHeader is used. DeviceNameHeader string // ConveyHeader is the name of the HTTP request header which contains the // base64-encoded JSON payload to forward with each outbound device request. // If not specified, DefaultConveyHeader is used. ConveyHeader string // HandshakeTimeout is the optional websocket handshake timeout. If not supplied, // the internal gorilla default is used. HandshakeTimeout time.Duration // InitialCapacity is used as the starting capacity of the internal map of // registered devices. If not supplied, DefaultInitialCapacity is used. InitialCapacity int // ReadBufferSize is the optional size of websocket read buffers. If not supplied, // the internal gorilla default is used. ReadBufferSize int // WriteBufferSize is the optional size of websocket write buffers. If not supplied, // the internal gorilla default is used. WriteBufferSize int // Subprotocols is the optional slice of websocket subprotocols to use. Subprotocols []string // DeviceMessageQueueSize is the capacity of the channel which stores messages waiting // to be transmitted to a device. If not supplied, DefaultDeviceMessageQueueSize is used. DeviceMessageQueueSize int // PingPeriod is the time between pings sent to each device PingPeriod time.Duration // IdlePeriod is the length of time a device connection is allowed to be idle, // with no traffic coming from the device. If not supplied, DefaultIdlePeriod is used. IdlePeriod time.Duration // WriteTimeout is the write timeout for each device's websocket. If not supplied, // DefaultWriteTimeout is used. WriteTimeout time.Duration // MessageListener is the notification sink for device messages MessageListener MessageListener // ConnectListener receives notifications for device connections ConnectListener ConnectListener // DisconnectListener receives notifications when devices disconnect for any reason DisconnectListener DisconnectListener // PongListener is the notification sink for pongs PongListener PongListener // KeyFunc is the factory function for Keys, used when devices connect. // If this value is nil, then UUIDKeyFunc is used along with crypto/rand's Reader. KeyFunc KeyFunc // Logger is the output sink for log messages. If not supplied, log output // is sent to logging.DefaultLogger(). Logger logging.Logger }
Options represent the available configuration options for device Managers and ConnectionFactories.
type PongListener ¶
PongListener is a function which receives notifications when devices disconnect (or, are disconnected) from the system
func PongListeners ¶
func PongListeners(listeners ...PongListener) PongListener
PongListeners aggregates multiple listeners into one. If this method is passed zero (0) listeners, an internal default is used instead.