Author(s): Sam Whited
Last updated: 2020-02-26
Discussion: https://mellium.im/issue/25
An API is needed for multiplexing based on stanzas that allows for matching based on type and quickly replying or re-marshaling the original stanzas.
In the previous IQ mux proposal a new mechanism for routing IQ stanzas based on their type and payload was introduced. In practice, registering the IQ muxer ended up being cumbersome, and the previous proposal did not solve the problem of routing message or presence stanzas (this was deliberately left for a future proposal). To solve both of these problems at once the current multiplexer can be adapted using what we learned from the IQ mux experiment such that it can route message and presence stanzas based on their type, and IQs based on their type and payload.
Decoder.Decode
or Decoder.DecodeElement
In addition to the existing Handler
and IQHandler
types, the following
types would be added for messages and presence:
type MessageHandler interface {
HandleMessage(msg stanza.Message, t xmlstream.TokenReadEncoder) error
}
MessageHandler responds to message stanzas.
type PresenceHandler interface {
HandlePresence(p stanza.Presence, t xmlstream.TokenReadEncoder) error
}
PresenceHandler responds to presence stanzas.
Adapters for functions with the provided signature would also be made available,
similar to HandlerFunc
.
Decoding the entire payload using an xml.Decoder
requires the initial start
token which has already been consumed when creating the stanza.Message
,
stanza.IQ
, or stanza.Presence
.
We can't pass the start element instead of the decoded stanza type because this
limits future extensibility (we can add methods to the stanza type related to
encoding and decoding, replying, etc.), and it is undesirable to pass both
because then we are passing duplicate information to the handler.
Instead, we can prepend the start element to the buffered token stream so that
every handler has access to the entire stanza.
The existing IQ mux would be removed (this is a backwards incompatible change,
however, we are pre-1.0 and the IQ mux was never in a release) and its methods
and functionality would be added to ServeMux
.
The options related to registering stanzas would then be modified to take the new patterns as follows:
func IQ(typ stanza.IQType, payload xml.Name, h IQHandler) Option
IQ returns an option that matches IQ stanzas by type and payload name.
func Message(typ stanza.MessageType, payload xml.Name, h MessageHandler) Option
Message returns an option that matches message stanzas by type and
payload name.
func Presence(typ stanza.PresenceType, payload xml.Name, h PresenceHandler) Option
Presence returns an option that matches presence stanzas by type and
payload name.
Functional versions of these options (taking a HandlerFunc
) would also be
added.
Registering a handler that matches a stanza using the Handle
option will
cause a panic, but this behavior is subject to change in the future.