diff --git a/src/xmpp/stream.go b/src/xmpp/stream.go index b856341..0919ed3 100644 --- a/src/xmpp/stream.go +++ b/src/xmpp/stream.go @@ -95,6 +95,18 @@ func (stream *Stream) SendStart(start *xml.StartElement) (*xml.StartElement, err return rstart, nil } +// Send the end element that closes the stream. +func (stream *Stream) SendEnd(end *xml.EndElement) error { + buf := new(bytes.Buffer) + if err := writeXMLEndElement(buf, end); err != nil { + return err + } + if err := stream.send(buf.Bytes()); err != nil { + return err + } + return nil +} + // Send a stanza. Used to write a complete, top-level element. func (stream *Stream) Send(v interface{}) error { if stream.config.LogStanzas { diff --git a/src/xmpp/xmpp.go b/src/xmpp/xmpp.go index 20c5817..3137897 100644 --- a/src/xmpp/xmpp.go +++ b/src/xmpp/xmpp.go @@ -1,6 +1,7 @@ package xmpp import ( + "encoding/xml" "fmt" "log" "sync" @@ -8,6 +9,8 @@ import ( // Handles XMPP conversations over a Stream. Use NewClientXMPP or // NewComponentXMPP to create and configure a XMPP instance. +// Close the conversation by closing the Out channel, the In channel will be +// closed when the remote server closes its stream. type XMPP struct { // JID associated with the stream. Note: this may be negotiated with the @@ -158,9 +161,15 @@ func IqResult(id string) Matcher { } func (x *XMPP) sender() { + + // Send outgoing elements to the stream until the channel is closed. for v := range x.Out { x.stream.Send(v) } + + // Close the stream. Note: relies on common element name for all types of + // XMPP connection. + x.stream.SendEnd(&xml.EndElement{xml.Name{"stream", "stream"}}) } func (x *XMPP) receiver() {