/
doc.go
124 lines (123 loc) · 5.24 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2014 The Mellium Contributors.
// Use of this source code is governed by the BSD 2-clause
// license that can be found in the LICENSE file.
// Package xmpp provides functionality from the Extensible Messaging and
// Presence Protocol, sometimes known as "Jabber".
//
// It is subdivided into several packages; this package provides functionality
// for establishing an XMPP session, feature negotiation (including an API for
// defining your own stream features), and low-level connection and stream
// manipulation.
// The jid package provides an implementation of the XMPP address format.
//
//
// Session Negotiation
//
// To create an XMPP session, most users will want to call DialClientSession or
// DialServerSession to create a client-to-server (c2s) or server-to-server
// (s2s) connection respectively.
// These methods use sane defaults to dial a TCP connection and perform stream
// negotiation.
//
//
// session, err := xmpp.DialClientSession(
// context.TODO(), addr,
// xmpp.BindResource(),
// xmpp.StartTLS(true, nil),
// xmpp.SASL("", pass, sasl.ScramSha1Plus, sasl.ScramSha1, sasl.Plain),
// )
//
// If control over DNS or HTTP-based service discovery is desired, the user can
// create a Dialer or use DialClient (c2s) or DialServer (s2s).
// To use the resulting connection, or to use something other than a TCP
// connection (eg. to communicate over a Unix domain socket, an in-memory pipe,
// etc.) the connection can be passed to NewClientSession or NewServerSession.
//
// conn, err := xmpp.DialClient(context.TODO(), "tcp", addr)
// …
// session, err := xmpp.NewClientSession(
// context.TODO(), addr, conn,
// xmpp.BindResource(),
// xmpp.StartTLS(true, nil),
// xmpp.SASL("", pass, sasl.ScramSha1Plus, sasl.ScramSha1, sasl.Plain),
// )
//
//
// If complete control over the session establishment process is needed the
// NegotiateSession function can be used to support custom session negotiation
// protocols or to customize options around the default negotiator by using the
// NewNegotiator function.
//
// session, err := xmpp.NegotiateSession(
// context.TODO(), addr.Domain(), addr, conn,
// xmpp.NewNegotiator(xmpp.StreamConfig{
// Lang: "en",
// …
// }),
// )
//
// The default Negotiator and related functions use a list of StreamFeature's to
// negotiate the state of the session.
// Implementations of the most common features (StartTLS, SASL-based
// authentication, and resource binding) are provided.
// Custom stream features may be created using the StreamFeature struct.
// Stream features defined in this module are safe for concurrent use by
// multiple goroutines and for efficiency should only be created once and
// re-used.
//
// Handling Stanzas
//
// Unlike HTTP, the XMPP protocol is asynchronous, meaning that both clients and
// servers can accept and send requests at any time and responses are not
// required or may be received out of order.
// This is accomplished with two XML streams: an input stream and an output
// stream.
// To receive XML on the input stream, Session implements the xml.TokenReader
// interface defined in encoding/xml; this allows session to be wrapped with
// xml.NewTokenDecoder.
// To send XML on the output stream, Session has an EncodeToken method like the
// "mellium.im/xmlstream".TokenWriter interface.
// The session may also buffer writes and has a Flush method which will write
// any buffered XML to the underlying connection.
//
// However, writing individual XML tokens can be tedious and error prone.
// The mellium.im/xmpp/stanza package contains functions and structs that aid in
// the construction of message, presence and IQ elements which have special
// semantics in XMPP and are known as "stanzas".
// These can be sent with the Send and SendElement methods.
//
// // Send initial presence to let the server know we want to receive messages.
// _, err = session.Send(stanza.WrapPresence(nil, stanza.AvailablePresence, nil))
//
// For Send to correctly handle IQ responses, and to make the common case of
// polling for incoming XML on the input stream—and possibly writing to the
// output stream in response—easier, we need a long running goroutine.
// Session includes the Serve method for starting this processing.
// Serve provides a Handler with access to the stream but prevents it from
// advancing the stream beyond the current element and always advances the
// stream to the end of the element when the handler returns (even if the
// handler did not consume the entire element).
//
// err := session.Serve(xmpp.HandlerFunc(func(t xmlstream.TokenReadWriter, start *xml.StartElement) error {
// d := xml.NewTokenDecoder(t)
//
// // Ignore anything that's not a message.
// if start.Name.Local != "message" {
// return nil
// }
//
// msg := struct {
// stanza.Message
// Body string `xml:"body"`
// }{}
// err := d.DecodeElement(&msg, start)
// …
// if msg.Body != "" {
// log.Println("Got message: %q", msg.Body)
// }
// }))
//
// Be Advised
//
// This API is unstable and subject to change.
package xmpp // import "mellium.im/xmpp"