Documentation
¶
Overview ¶
Package wire implements the MQTT v5 wire-format codec. It is the foundation layer of the mqttv5 client and is the only package that touches packet bytes directly.
Goals:
- Zero allocations on the receive path in steady state. Frames are drawn from a pool; packet structs reference the frame buffer for string/byte fields rather than copying.
- Lazy property decoding: property bytes are kept as a slice until a consumer asks for a specific property by ID.
- PUBLISH encoders for each lifetime: AppendPublishHeader encodes everything but the payload, so header and payload go out together (net.Buffers, one writev) without copying the payload; EncodePublish encodes the whole packet into a pooled buffer for a write that happens later; MarshalPublish into an owned, exact-size slice for a packet that is kept.
Lifetime contract:
A Packet returned from a Decoder borrows its underlying frame buffer. The caller MUST call Packet.Release once they are done. After Release, every []byte and string field is invalid — copy what you need to keep (use strings.Clone, bytes.Clone, or assignment into a heap struct).
Index ¶
- Constants
- Variables
- func AppendPubResp(dst []byte, t PacketType, id uint16, rc ReasonCode) []byte
- func AppendPublishHeader(dst []byte, opts PublishOpts) ([]byte, error)
- func DecodeVarint(buf []byte) (value uint32, n int, err error)
- func EncodePublish(opts PublishOpts) (*[]byte, error)
- func EncodeVarint(buf []byte, v uint32) (int, error)
- func IsSharedFilter(filter string) bool
- func MarshalPublish(opts PublishOpts) ([]byte, error)
- func ReadVarint(r io.ByteReader) (value uint32, n int, err error)
- func ReleaseBuf(bp *[]byte)
- func ValidTopicFilter(filter string) error
- func ValidTopicName(name string) error
- func VarintSize(v uint32) int
- func WithMessageExpiry(frame []byte, seconds uint32) []byte
- func WriteAuth(w io.Writer, opts AuthOpts) (int64, error)
- func WriteConnack(w io.Writer, opts ConnackOpts) (int64, error)
- func WriteConnect(w io.Writer, opts ConnectOpts) (int64, error)
- func WriteDisconnect(w io.Writer, opts DisconnectOpts) (int64, error)
- func WritePingreq(w io.Writer) (int64, error)
- func WritePingresp(w io.Writer) (int64, error)
- func WritePuback(w io.Writer, opts PubRespOpts) (int64, error)
- func WritePubcomp(w io.Writer, opts PubRespOpts) (int64, error)
- func WritePublish(w io.Writer, opts PublishOpts) (int64, error)
- func WritePubrec(w io.Writer, opts PubRespOpts) (int64, error)
- func WritePubrel(w io.Writer, opts PubRespOpts) (int64, error)
- func WriteSuback(w io.Writer, opts SubackOpts) (int64, error)
- func WriteSubscribe(w io.Writer, opts SubscribeOpts) (int64, error)
- func WriteUnsuback(w io.Writer, opts UnsubackOpts) (int64, error)
- func WriteUnsubscribe(w io.Writer, opts UnsubscribeOpts) (int64, error)
- type Auth
- type AuthOpts
- type Connack
- type ConnackOpts
- type Connect
- type ConnectOpts
- type Decoder
- type Disconnect
- type DisconnectOpts
- type FixedHeader
- type Packet
- type PacketError
- type PacketType
- type Pingreq
- type Pingresp
- type Properties
- func (p Properties) Binary(id byte) ([]byte, bool)
- func (p Properties) Byte(id byte) (byte, bool)
- func (p Properties) Len() int
- func (p Properties) Raw() []byte
- func (p Properties) String(id byte) (string, bool)
- func (p Properties) SubscriptionIdentifiers() iter.Seq[uint32]
- func (p Properties) Uint16(id byte) (uint16, bool)
- func (p Properties) Uint32(id byte) (uint32, bool)
- func (p Properties) UserProperties() iter.Seq2[string, string]
- func (p Properties) Varint(id byte) (uint32, bool)
- type PubResp
- type PubRespOpts
- type Publish
- type PublishOpts
- type ReasonCode
- type Suback
- type SubackOpts
- type Subscribe
- type SubscribeFilter
- type SubscribeOpts
- type Unsuback
- type UnsubackOpts
- type Unsubscribe
- type UnsubscribeOpts
- type UserProperty
- type Will
- type WillOpts
Constants ¶
const ( PropPayloadFormat byte = 0x01 PropMessageExpiryInterval byte = 0x02 PropContentType byte = 0x03 PropResponseTopic byte = 0x08 PropCorrelationData byte = 0x09 PropSubscriptionIdentifier byte = 0x0B PropSessionExpiryInterval byte = 0x11 PropAssignedClientID byte = 0x12 PropServerKeepAlive byte = 0x13 PropAuthMethod byte = 0x15 PropAuthData byte = 0x16 PropRequestProblemInfo byte = 0x17 PropWillDelayInterval byte = 0x18 PropRequestResponseInfo byte = 0x19 PropResponseInformation byte = 0x1A PropServerReference byte = 0x1C PropReasonString byte = 0x1F PropReceiveMaximum byte = 0x21 PropTopicAliasMaximum byte = 0x22 PropTopicAlias byte = 0x23 PropMaximumQoS byte = 0x24 PropRetainAvailable byte = 0x25 PropUserProperty byte = 0x26 PropMaximumPacketSize byte = 0x27 PropWildcardSubAvailable byte = 0x28 PropSubscriptionIDAvailable byte = 0x29 )
Property IDs as defined in MQTT v5 §2.2.2.2. Every PropID listed here is single-byte on the wire; the spec permits VBI but reserves nothing above 0x2A, so a fast byte path is correct for every conforming implementation.
const DefaultReadBufferSize = 4096
DefaultReadBufferSize is the bufio.Reader window NewDecoder uses: how many bytes one read syscall can bring in. Packets larger than the window are read straight into their frame buffer.
const MaxVarintValue uint32 = 268_435_455
MaxVarintValue is the largest value an MQTT v5 Variable Byte Integer can represent: 268,435,455 (2^28 - 1). See MQTT 5 §1.5.5.
const ProtocolName = "MQTT"
ProtocolName is the canonical UTF-8 name carried in every CONNECT.
const ProtocolVersion byte = 5
ProtocolVersion is the byte we send (and require) in CONNECT for v5.
Variables ¶
var ( // ErrVarintTooLarge is returned when encoding a value above MaxVarintValue. ErrVarintTooLarge = errors.New("mqttv5: variable byte integer exceeds maximum (268435455)") // ErrVarintMalformed is returned when a varint encoding does not // terminate within 4 bytes, or the input buffer is exhausted before // the encoding completes. ErrVarintMalformed = errors.New("mqttv5: malformed variable byte integer") )
var ( // ErrInvalidTopic marks a topic name or filter that breaks §4.7. ErrInvalidTopic = errors.New("mqttv5: invalid topic") // ErrStringTooLong marks a UTF-8 string or binary field longer than // the 65,535 bytes its 2-byte length prefix can describe. ErrStringTooLong = errors.New("mqttv5: field longer than 65535 bytes") )
var ErrEmptyFilterList = fmt.Errorf("mqttv5: subscribe/unsubscribe requires at least one filter")
ErrEmptyFilterList is returned when WriteSubscribe / WriteUnsubscribe is called with no filters; the protocol requires at least one.
var ErrInvalidField = errors.New("mqttv5: invalid field")
ErrInvalidField marks an option value MQTT v5 does not allow; the packet is not written.
var ErrInvalidPacket = errors.New("mqttv5: invalid packet")
ErrInvalidPacket is returned for packets that violate MQTT structure (bad flags for the type, oversized properties section, etc.).
var ErrInvalidProperties = errors.New("mqttv5: malformed properties")
ErrInvalidProperties is returned when the property bytes are structurally malformed (truncated value, unknown property ID).
var ErrInvalidProtocol = fmt.Errorf("mqttv5: invalid protocol name or version")
ErrInvalidProtocol is returned when a CONNECT carries a protocol name other than "MQTT" or a version other than 5.
var ErrInvalidQoS = errors.New("mqttv5: QoS must be 0, 1, or 2")
ErrInvalidQoS is returned by WritePublish when opts.QoS is not 0, 1, or 2.
var ErrPacketIDRequired = errors.New("mqttv5: PacketID required for QoS > 0")
ErrPacketIDRequired is returned by WritePublish when QoS > 0 and PacketID is 0 (packet ID 0 is reserved).
var ErrPacketTooLarge = errors.New("mqttv5: packet exceeds the maximum packet size")
ErrPacketTooLarge is returned by Decoder.ReadPacket when a packet's declared size exceeds the limit set with SetMaxPacketSize. The body is not read, so the stream cannot be resumed.
var ErrTruncated = errors.New("mqttv5: truncated packet")
ErrTruncated is returned when a packet body ends before a required field has been fully read. Caller context (which field) is wrapped via fmt.Errorf at the call site so we keep allocations down here.
var ErrUnsupportedPacket = errors.New("mqttv5: unknown packet type")
ErrUnsupportedPacket is returned by Decoder.ReadPacket when the fixed header carries a packet type outside the MQTT v5 set (i.e. a reserved or unknown value). All standard v5 packet types decode.
Functions ¶
func AppendPubResp ¶ added in v0.11.0
func AppendPubResp(dst []byte, t PacketType, id uint16, rc ReasonCode) []byte
AppendPubResp appends a property-less PUBACK, PUBREC, PUBREL or PUBCOMP to dst and returns the extended slice. A Success reason code is omitted (§3.4.2.2.1), giving the minimal 4-byte frame; any other code adds one byte. It never allocates when dst has room.
func AppendPublishHeader ¶ added in v0.11.0
func AppendPublishHeader(dst []byte, opts PublishOpts) ([]byte, error)
AppendPublishHeader appends to dst the PUBLISH packet opts describes, up to its payload: the fixed header, whose Remaining Length counts the payload, the variable header and the properties. The header followed by opts.Payload is the whole packet, so a caller that writes the two together — one writev through net.Buffers — sends the packet without copying the payload.
func DecodeVarint ¶
DecodeVarint parses a VBI from the head of buf, returning the decoded value, byte count consumed, and any error. Used on already-buffered frames (properties, packet bodies). Zero allocations.
func EncodePublish ¶
func EncodePublish(opts PublishOpts) (*[]byte, error)
EncodePublish encodes a PUBLISH into a pooled []byte and returns a pointer to it. The caller MUST call ReleaseBuf on the returned pointer after sending the bytes (or on any error path that discards them).
This is the zero-closure-alloc path used by the client's QoS 0 fire-and-forget Publish — pre-encoding lets the call avoid capturing PublishOpts into a writer closure, and the bytes can later be batched with other reqs into a single writev.
Returned slice contents are valid until ReleaseBuf is called.
func EncodeVarint ¶
EncodeVarint writes the VBI encoding of v into buf and returns the byte count. buf must have capacity ≥ 4. Returns ErrVarintTooLarge if v exceeds MaxVarintValue.
Zero allocations: caller supplies the buffer (typical pattern is a stack-allocated [4]byte).
func IsSharedFilter ¶ added in v0.11.0
IsSharedFilter reports whether filter names a shared subscription.
func MarshalPublish ¶ added in v0.11.0
func MarshalPublish(opts PublishOpts) ([]byte, error)
MarshalPublish encodes a PUBLISH into a new, exactly-sized slice owned by the caller. Use it for packets that outlive a write, such as QoS 1/2 publishes kept for retransmission; EncodePublish is the pooled variant for packets released right after the write.
func ReadVarint ¶
func ReadVarint(r io.ByteReader) (value uint32, n int, err error)
ReadVarint reads a VBI byte-at-a-time from r. Used to parse the fixed header's Remaining Length before the body has been buffered. The returned byte count is what was consumed from r (≤ 4).
func ReleaseBuf ¶
func ReleaseBuf(bp *[]byte)
ReleaseBuf returns a buffer obtained from EncodePublish (or any other caller-facing acquireBuf variant we expose) back to the pool. Safe against nil.
func ValidTopicFilter ¶ added in v0.11.0
ValidTopicFilter checks a subscription topic filter (§4.7): non-empty well-formed UTF-8, '#' only as the whole last level, '+' only as a whole level, and for a shared subscription ($share/{ShareName}/{filter}) a non-empty ShareName without '/', '+' or '#' and a valid filter.
func ValidTopicName ¶ added in v0.11.0
ValidTopicName checks a PUBLISH topic name (§4.7): a well-formed UTF-8 string of at most 65,535 bytes without wildcard characters. An empty name is allowed only together with a Topic Alias, which the caller checks.
func VarintSize ¶
VarintSize reports the number of bytes EncodeVarint would write for v. Returns 0 if v exceeds MaxVarintValue (caller should treat as error).
func WithMessageExpiry ¶ added in v0.11.0
WithMessageExpiry returns a copy of the encoded PUBLISH frame with its Message Expiry Interval set to seconds. Frames that carry no expiry property, or that cannot be parsed, are returned unchanged. Used when a stored message is sent again later than it was first encoded (§3.3.2.3.3).
func WriteConnack ¶
func WriteConnack(w io.Writer, opts ConnackOpts) (int64, error)
WriteConnack emits a CONNACK packet.
func WriteConnect ¶
func WriteConnect(w io.Writer, opts ConnectOpts) (int64, error)
WriteConnect emits a CONNECT packet.
func WriteDisconnect ¶
func WriteDisconnect(w io.Writer, opts DisconnectOpts) (int64, error)
WriteDisconnect emits a DISCONNECT packet.
func WritePingreq ¶
WritePingreq emits a PINGREQ packet (2 bytes: type byte + 0 remaining length).
func WritePingresp ¶
WritePingresp emits a PINGRESP packet (2 bytes).
func WritePuback ¶
func WritePuback(w io.Writer, opts PubRespOpts) (int64, error)
WritePuback emits a PUBACK packet.
func WritePubcomp ¶
func WritePubcomp(w io.Writer, opts PubRespOpts) (int64, error)
WritePubcomp emits a PUBCOMP packet.
func WritePublish ¶
func WritePublish(w io.Writer, opts PublishOpts) (int64, error)
WritePublish encodes a PUBLISH packet and writes it to w as its header (AppendPublishHeader) followed by the payload, which is not copied. Writers that support vectored I/O (*net.TCPConn, *net.UnixConn) send both in one writev.
func WritePubrec ¶
func WritePubrec(w io.Writer, opts PubRespOpts) (int64, error)
WritePubrec emits a PUBREC packet.
func WritePubrel ¶
func WritePubrel(w io.Writer, opts PubRespOpts) (int64, error)
WritePubrel emits a PUBREL packet. The fixed-header flag nibble is 0x02 per §3.6.1.
func WriteSuback ¶
func WriteSuback(w io.Writer, opts SubackOpts) (int64, error)
WriteSuback emits a SUBACK packet.
func WriteSubscribe ¶
func WriteSubscribe(w io.Writer, opts SubscribeOpts) (int64, error)
WriteSubscribe emits a SUBSCRIBE packet (flags = 0x02).
func WriteUnsuback ¶
func WriteUnsuback(w io.Writer, opts UnsubackOpts) (int64, error)
WriteUnsuback emits an UNSUBACK packet.
func WriteUnsubscribe ¶
func WriteUnsubscribe(w io.Writer, opts UnsubscribeOpts) (int64, error)
WriteUnsubscribe emits an UNSUBSCRIBE packet (flags = 0x02).
Types ¶
type Auth ¶
type Auth struct {
ReasonCode ReasonCode
Properties Properties
// contains filtered or unexported fields
}
Auth is a decoded AUTH packet (MQTT v5 §3.15).
Per §3.15.2.2.1, when RemainingLength == 0 the Reason Code is implied Success and no properties are present.
type AuthOpts ¶
type AuthOpts struct {
ReasonCode ReasonCode
AuthenticationMethod string
AuthenticationData []byte
ReasonString string
UserProperties []UserProperty
}
AuthOpts is the input for WriteAuth.
type Connack ¶
type Connack struct {
SessionPresent bool
ReasonCode ReasonCode
Properties Properties
// contains filtered or unexported fields
}
Connack is a decoded CONNACK packet (§3.2). Properties is a lazy view over the property section.
func (*Connack) Clone ¶
Clone returns a deep copy of c that is safe to retain past the originating frame's lifetime. The clone is not pooled — let it be garbage-collected; do not call Release on it.
type ConnackOpts ¶
type ConnackOpts struct {
SessionPresent bool
ReasonCode ReasonCode
SessionExpiryInterval *uint32
ReceiveMaximum *uint16
MaximumQoS *byte
RetainAvailable *byte
MaximumPacketSize *uint32
AssignedClientIdentifier string
TopicAliasMaximum uint16
ReasonString string
UserProperties []UserProperty
WildcardSubscriptionAvailable *byte
SubscriptionIdentifierAvailable *byte
ServerKeepAlive *uint16
ResponseInformation string
ServerReference string
AuthenticationMethod string
AuthenticationData []byte
}
ConnackOpts is the input for WriteConnack.
type Connect ¶
type Connect struct {
ProtocolName string
ProtocolVersion byte
CleanStart bool
KeepAlive uint16
Properties Properties
ClientID string
Username string
Password []byte
Will *Will
// contains filtered or unexported fields
}
Connect is a decoded CONNECT packet (§3.1).
Properties is a lazy view over the CONNECT properties section. Will is non-nil iff the Will Flag was set on the wire. Username / Password are empty / nil when their flags were not set.
type ConnectOpts ¶
type ConnectOpts struct {
ClientID string
CleanStart bool
KeepAlive uint16
Username string // empty = no Username Flag
Password []byte // nil = no Password Flag
Will *WillOpts // nil = no Will Flag
SessionExpiryInterval *uint32
ReceiveMaximum *uint16
MaximumPacketSize *uint32
TopicAliasMaximum uint16
RequestResponseInformation *byte
RequestProblemInformation *byte
UserProperties []UserProperty
AuthenticationMethod string
AuthenticationData []byte
}
ConnectOpts is the input for WriteConnect.
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder reads MQTT v5 control packets from an underlying io.Reader.
Each Decoder owns one bufio.Reader and one allocation footprint — per-packet allocations come only from the frame and packet pools. Decoders are not safe for concurrent ReadPacket calls; one Decoder per connection is the intended pattern.
func NewDecoder ¶
NewDecoder wraps r in a Decoder with a DefaultReadBufferSize window.
func NewDecoderSize ¶ added in v0.11.0
NewDecoderSize wraps r in a Decoder whose read window is size bytes. Larger windows mean fewer read syscalls for streams of small packets.
func (*Decoder) ReadPacket ¶
ReadPacket reads one control packet from the underlying reader and checks it against MQTT v5: fixed-header flags, minimal Remaining Length, the properties each packet may carry and their values, UTF-8 strings, topic names and filters, packet identifiers and reason codes. A violation is returned as a *PacketError whose Reason is the DISCONNECT code to close with; the stream cannot be resumed after it.
The returned Packet borrows pooled memory; the caller MUST call Packet.Release once they are done reading its fields. Failing to do so leaks frame buffers; calling it twice corrupts the pool.
Returns io.EOF when the underlying reader is exhausted between packets and io.ErrUnexpectedEOF if a packet is truncated mid-stream.
func (*Decoder) Ready ¶ added in v0.11.0
Ready reports whether a whole packet is buffered, so the next ReadPacket returns without reading from the connection.
func (*Decoder) Reset ¶
Reset re-points the Decoder at a new reader, reusing the internal bufio buffer. Production callers use this on reconnect.
func (*Decoder) SetLenient ¶ added in v0.11.0
func (d *Decoder) SetLenient(report func(*PacketError))
SetLenient makes ReadPacket accept the violations that are harmless in practice — a non-minimally encoded Remaining Length and reserved flag bits on PINGRESP — reporting each to report instead of failing. Every other violation still fails. Nil restores strict decoding.
func (*Decoder) SetMaxPacketSize ¶ added in v0.11.0
SetMaxPacketSize makes ReadPacket reject packets whose total size — fixed header included, as MQTT's Maximum Packet Size counts it (§3.1.2.11.4) — exceeds n. Zero removes the limit.
type Disconnect ¶
type Disconnect struct {
ReasonCode ReasonCode
Properties Properties
// contains filtered or unexported fields
}
Disconnect is a decoded DISCONNECT packet (MQTT v5 §3.14).
Per §3.14.2.2.1, the Reason Code defaults to 0x00 (Normal Disconnection) when RemainingLength == 0; the Properties section is implied empty when RemainingLength <= 1.
func (*Disconnect) Clone ¶
func (d *Disconnect) Clone() *Disconnect
Clone returns a deep copy of d that is safe to retain past the originating frame's lifetime. The clone is not pooled — let it be garbage-collected; do not call Release on it.
func (*Disconnect) Release ¶
func (d *Disconnect) Release()
Release returns the packet and its frame to their pools.
type DisconnectOpts ¶
type DisconnectOpts struct {
ReasonCode ReasonCode
SessionExpiryInterval *uint32
ReasonString string
ServerReference string
UserProperties []UserProperty
}
DisconnectOpts is the input for WriteDisconnect. ReasonCode default (zero = NormalDisconnection) plus no properties yields a minimal 2-byte packet.
type FixedHeader ¶
type FixedHeader struct {
Type PacketType
Flags byte
RemainingLength uint32
}
FixedHeader is the 2-5 byte MQTT fixed header. Type occupies the high nibble of byte 1; Flags the low nibble. RemainingLength is a VBI.
type Packet ¶
type Packet interface {
Type() PacketType
Release()
}
Packet is the polymorphic return value from Decoder.ReadPacket. Each concrete type (Publish, Connack, etc.) implements it.
Release returns the packet and its frame buffer to their respective pools. Calling Release more than once is a programming error and may corrupt pooled memory.
type PacketError ¶ added in v0.11.0
type PacketError struct {
Packet PacketType
Reason ReasonCode
Detail string
}
PacketError reports a packet that breaks MQTT v5. Reason is the code a receiver must close the connection with: 0x81 (Malformed Packet) for packets that cannot be parsed as the spec defines them, 0x82 (Protocol Error) for well-formed packets that break a protocol rule. errors.Is matches it against ErrInvalidPacket.
func (*PacketError) Error ¶ added in v0.11.0
func (e *PacketError) Error() string
func (*PacketError) Unwrap ¶ added in v0.11.0
func (e *PacketError) Unwrap() error
Unwrap lets errors.Is(err, ErrInvalidPacket) match.
type PacketType ¶
type PacketType byte
PacketType is the MQTT control packet type byte (high nibble of byte 1).
const ( CONNECT PacketType = 1 CONNACK PacketType = 2 PUBLISH PacketType = 3 PUBACK PacketType = 4 PUBREC PacketType = 5 PUBREL PacketType = 6 PUBCOMP PacketType = 7 SUBSCRIBE PacketType = 8 SUBACK PacketType = 9 UNSUBSCRIBE PacketType = 10 UNSUBACK PacketType = 11 PINGREQ PacketType = 12 PINGRESP PacketType = 13 DISCONNECT PacketType = 14 AUTH PacketType = 15 )
MQTT v5 control packet types (§2.1.2).
func (PacketType) String ¶
func (t PacketType) String() string
String returns the protocol name of the type.
type Pingreq ¶
type Pingreq struct{}
Pingreq is a PINGREQ packet (MQTT v5 §3.12). Empty body.
type Pingresp ¶
type Pingresp struct{}
Pingresp is a PINGRESP packet (MQTT v5 §3.13). Empty body.
type Properties ¶
type Properties struct {
// contains filtered or unexported fields
}
Properties is a zero-copy lazy view over an MQTT property section. The underlying bytes belong to a frame buffer owned by the enclosing Packet; once that packet is Released, the Properties value is invalid.
Lookups walk the raw bytes — O(N) in the number of properties. For packets where most callers only check one or two properties this beats pre-parsing into a map. For packets where every property is consumed (rare), an eager decode would win; switch strategies when a benchmark shows it.
func PropertiesFromBytes ¶
func PropertiesFromBytes(b []byte) Properties
PropertiesFromBytes wraps an already-parsed property byte slice. Used by tests and by per-packet decoders; production callers receive a Properties value attached to a decoded packet.
func (Properties) Binary ¶
func (p Properties) Binary(id byte) ([]byte, bool)
Binary returns the binary-data property value for id.
Zero-copy: the returned slice aliases the frame.
func (Properties) Byte ¶
func (p Properties) Byte(id byte) (byte, bool)
Byte returns the single-byte property value for id and whether it was present.
func (Properties) Len ¶
func (p Properties) Len() int
Len reports the byte length of the property section.
func (Properties) Raw ¶
func (p Properties) Raw() []byte
Raw returns the underlying property bytes (without the leading length VBI). Useful for re-encoding or for property types not yet exposed via dedicated accessors.
func (Properties) String ¶
func (p Properties) String(id byte) (string, bool)
String returns the UTF-8 string property value for id.
Zero-copy: the returned string shares memory with the underlying frame. Copy via strings.Clone if you need to retain it past packet Release.
func (Properties) SubscriptionIdentifiers ¶ added in v0.11.0
func (p Properties) SubscriptionIdentifiers() iter.Seq[uint32]
SubscriptionIdentifiers yields every Subscription Identifier on a PUBLISH, one per subscription of the receiver that matched it (§3.3.2.3.8).
func (Properties) Uint16 ¶
func (p Properties) Uint16(id byte) (uint16, bool)
Uint16 returns the 2-byte big-endian property value for id and whether it was present.
func (Properties) Uint32 ¶
func (p Properties) Uint32(id byte) (uint32, bool)
Uint32 returns the 4-byte big-endian property value for id.
func (Properties) UserProperties ¶
func (p Properties) UserProperties() iter.Seq2[string, string]
UserProperties yields all user-property key/value pairs in the order they appear on the wire. Zero allocations for the iteration itself — each yielded string aliases the frame.
type PubResp ¶
type PubResp struct {
PacketID uint16
ReasonCode ReasonCode
Properties Properties
// contains filtered or unexported fields
}
PubResp is the shared decoded form for the four publish-response packets: PUBACK, PUBREC, PUBREL, PUBCOMP. They have identical wire shape (PacketID + optional ReasonCode + optional Properties) and differ only in their type byte and PUBREL's reserved-flag value.
Inspect Type() to know which of the four arrived.
func (*PubResp) Release ¶
func (p *PubResp) Release()
Release returns the packet and its frame to their pools.
func (*PubResp) Type ¶
func (p *PubResp) Type() PacketType
Type returns the concrete packet type — one of PUBACK, PUBREC, PUBREL, PUBCOMP.
type PubRespOpts ¶
type PubRespOpts struct {
PacketID uint16
ReasonCode ReasonCode
ReasonString string
UserProperties []UserProperty
}
PubRespOpts is the input for WritePuback / Pubrec / Pubrel / Pubcomp. Per §3.4.2.2.1, when ReasonCode is Success AND there are no properties, the encoded packet omits both — yielding a minimal 4-byte frame (fixed header + 2-byte PacketID).
type Publish ¶
type Publish struct {
// Topic aliases the frame. Copy via strings.Clone to retain past Release.
Topic string
// Payload aliases the frame. Copy via bytes.Clone to retain past Release.
Payload []byte
// Properties is a lazy view into the frame.
Properties Properties
QoS byte
Retain bool
Dup bool
PacketID uint16
// contains filtered or unexported fields
}
Publish is a decoded PUBLISH packet. Topic, Payload, and Properties reference the underlying frame buffer; they become invalid once Release is called.
For an outbound publish, build a PublishOpts and call WritePublish — this type is for receivers only.
func (*Publish) Opts ¶ added in v0.11.0
func (p *Publish) Opts() PublishOpts
Opts returns options that encode this PUBLISH again: topic, payload, QoS, flags, packet identifier and every property a client may send, with optional properties present exactly when they are here (an empty Correlation Data stays non-nil; an empty payload is nil). Subscription Identifiers, which only a server sends, are left out. The result owns copies of its fields and stays valid after Release.
func (*Publish) Pooled ¶ added in v0.11.0
Pooled reports whether Release recycles the packet's frame, which invalidates the Topic, Payload and Properties views. A frame larger than the biggest pool class is never recycled: those views stay valid after Release for as long as they are referenced.
type PublishOpts ¶
type PublishOpts struct {
Topic string
Payload []byte
QoS byte // 0, 1, or 2
Retain bool
Dup bool // must be false for QoS 0
PacketID uint16 // required when QoS > 0
// Properties (all optional). Only set what you mean to send.
PayloadFormatIndicator *byte
MessageExpiryInterval *uint32
ContentType string
ResponseTopic string
CorrelationData []byte
TopicAlias uint16 // 0 = unset (alias 0 is reserved by spec)
UserProperties []UserProperty
}
PublishOpts is the input for WritePublish. All pointer-typed property fields are skipped when nil; string fields are skipped when empty; TopicAlias is skipped when 0 (per MQTT v5, alias 0 is reserved).
func (PublishOpts) Clone ¶ added in v0.11.0
func (o PublishOpts) Clone() PublishOpts
Clone returns a deep copy of o: no slice or pointed-to value is shared with o, and nil stays nil.
type ReasonCode ¶
type ReasonCode byte
ReasonCode is the single-byte reason code carried by CONNACK, PUBACK/REC/REL/COMP, SUBACK, UNSUBACK, DISCONNECT, and AUTH. The meaning of each value is context-dependent — see MQTT v5 §3.x.2 for which codes are valid in which packets.
const ( ReasonSuccess ReasonCode = 0x00 // CONNACK, PUBACK/REC/REL/COMP, SUBACK, UNSUBACK ReasonNormalDisconnection ReasonCode = 0x00 // DISCONNECT ReasonGrantedQoS0 ReasonCode = 0x00 // SUBACK ReasonGrantedQoS1 ReasonCode = 0x01 // SUBACK ReasonGrantedQoS2 ReasonCode = 0x02 // SUBACK ReasonDisconnectWithWill ReasonCode = 0x04 // DISCONNECT ReasonNoMatchingSubscribers ReasonCode = 0x10 // PUBACK, PUBREC ReasonNoSubscriptionExisted ReasonCode = 0x11 // UNSUBACK ReasonContinueAuthentication ReasonCode = 0x18 // AUTH ReasonReAuthenticate ReasonCode = 0x19 // AUTH )
Success and granted-QoS codes (0x00 – 0x04).
const ( ReasonUnspecifiedError ReasonCode = 0x80 ReasonMalformedPacket ReasonCode = 0x81 ReasonProtocolError ReasonCode = 0x82 ReasonImplementationSpecificError ReasonCode = 0x83 ReasonUnsupportedProtocolVersion ReasonCode = 0x84 // CONNACK ReasonClientIdentifierNotValid ReasonCode = 0x85 // CONNACK ReasonBadUsernameOrPassword ReasonCode = 0x86 // CONNACK ReasonNotAuthorized ReasonCode = 0x87 ReasonServerBusy ReasonCode = 0x89 ReasonBanned ReasonCode = 0x8A // CONNACK ReasonServerShuttingDown ReasonCode = 0x8B // DISCONNECT ReasonBadAuthenticationMethod ReasonCode = 0x8C ReasonKeepAliveTimeout ReasonCode = 0x8D // DISCONNECT ReasonSessionTakenOver ReasonCode = 0x8E // DISCONNECT ReasonTopicFilterInvalid ReasonCode = 0x8F ReasonTopicNameInvalid ReasonCode = 0x90 ReasonPacketIdentifierInUse ReasonCode = 0x91 // PUBACK, PUBREC, SUBACK, UNSUBACK ReasonPacketIdentifierNotFound ReasonCode = 0x92 // PUBREL, PUBCOMP ReasonReceiveMaximumExceeded ReasonCode = 0x93 // DISCONNECT ReasonTopicAliasInvalid ReasonCode = 0x94 // DISCONNECT ReasonPacketTooLarge ReasonCode = 0x95 ReasonMessageRateTooHigh ReasonCode = 0x96 // DISCONNECT ReasonQuotaExceeded ReasonCode = 0x97 ReasonAdministrativeAction ReasonCode = 0x98 // DISCONNECT ReasonPayloadFormatInvalid ReasonCode = 0x99 ReasonRetainNotSupported ReasonCode = 0x9A ReasonQoSNotSupported ReasonCode = 0x9B ReasonUseAnotherServer ReasonCode = 0x9C ReasonServerMoved ReasonCode = 0x9D ReasonConnectionRateExceeded ReasonCode = 0x9F ReasonMaximumConnectTime ReasonCode = 0xA0 // DISCONNECT ReasonSubscriptionIDsNotSupported ReasonCode = 0xA1 // SUBACK, DISCONNECT ReasonWildcardSubscriptionsNotSupported ReasonCode = 0xA2 // SUBACK, DISCONNECT )
Error and refusal codes (0x80 – 0xA2).
func (ReasonCode) IsError ¶
func (r ReasonCode) IsError() bool
IsError reports whether the reason code indicates an error (high bit set).
type Suback ¶
type Suback struct {
PacketID uint16
Properties Properties
ReasonCodes []ReasonCode
// contains filtered or unexported fields
}
Suback is a decoded SUBACK packet (§3.9). One Reason per filter in the SUBSCRIBE this SUBACK responds to.
type SubackOpts ¶
type SubackOpts struct {
PacketID uint16
ReasonCodes []ReasonCode
ReasonString string
UserProperties []UserProperty
}
SubackOpts is the input for WriteSuback.
type Subscribe ¶
type Subscribe struct {
PacketID uint16
Properties Properties
Filters []SubscribeFilter
// contains filtered or unexported fields
}
Subscribe is a decoded SUBSCRIBE packet (§3.8).
Filters slice references the decoded list (one allocation per packet decode — SUBSCRIBE is infrequent, lazy parsing would be premature).
type SubscribeFilter ¶
type SubscribeFilter struct {
Topic string
QoS byte // 0, 1, 2
NoLocal bool
RetainAsPublished bool
RetainHandling byte // 0, 1, 2 — see MQTT v5 §3.8.3.1
}
SubscribeFilter is one entry in the SUBSCRIBE payload: a topic filter plus its subscription options byte (§3.8.3.1).
type SubscribeOpts ¶
type SubscribeOpts struct {
PacketID uint16
Filters []SubscribeFilter
SubscriptionIdentifier *uint32
UserProperties []UserProperty
}
SubscribeOpts is the input for WriteSubscribe.
type Unsuback ¶
type Unsuback struct {
PacketID uint16
Properties Properties
ReasonCodes []ReasonCode
// contains filtered or unexported fields
}
Unsuback is a decoded UNSUBACK packet (§3.11). One Reason per topic in the UNSUBSCRIBE this UNSUBACK responds to.
type UnsubackOpts ¶
type UnsubackOpts struct {
PacketID uint16
ReasonCodes []ReasonCode
ReasonString string
UserProperties []UserProperty
}
UnsubackOpts is the input for WriteUnsuback.
type Unsubscribe ¶
type Unsubscribe struct {
PacketID uint16
Properties Properties
Topics []string
// contains filtered or unexported fields
}
Unsubscribe is a decoded UNSUBSCRIBE packet (§3.10). The Topics slice references the decoded list — one allocation per packet decode.
func (*Unsubscribe) Release ¶
func (u *Unsubscribe) Release()
Release returns the packet and its frame to their pools.
type UnsubscribeOpts ¶
type UnsubscribeOpts struct {
PacketID uint16
Topics []string
UserProperties []UserProperty
}
UnsubscribeOpts is the input for WriteUnsubscribe.
type UserProperty ¶
type UserProperty struct {
Key, Value string
}
UserProperty is a single key/value entry. Multiple may appear in one PUBLISH.
type Will ¶
type Will struct {
Topic string
Payload []byte
QoS byte
Retain bool
Properties Properties
}
Will is the decoded Will Message portion of a CONNECT packet (§3.1.3.2-§3.1.3.4). Topic, Payload, and Properties alias the frame.
type WillOpts ¶
type WillOpts struct {
Topic string
Payload []byte
QoS byte
Retain bool
WillDelayInterval *uint32
PayloadFormatIndicator *byte
MessageExpiryInterval *uint32
ContentType string
ResponseTopic string
CorrelationData []byte
UserProperties []UserProperty
}
WillOpts is the input for the Will portion of a ConnectOpts.