xmpp.go
changeset 28 78961db80bae
parent 27 13bcc96a5a6c
child 29 a456133ed0ac
equal deleted inserted replaced
27:13bcc96a5a6c 28:78961db80bae
    11 
    11 
    12 import (
    12 import (
    13 	"bytes"
    13 	"bytes"
    14 	"fmt"
    14 	"fmt"
    15 	"io"
    15 	"io"
       
    16 	"log"
    16 	"net"
    17 	"net"
    17 	"os"
    18 	"os"
    18 	"sync"
    19 	"sync"
       
    20 	"xml"
    19 )
    21 )
    20 
    22 
    21 const (
    23 const (
    22 	// Version of RFC 3920 that we implement.
    24 	// Version of RFC 3920 that we implement.
    23 	Version = "1.0"
    25 	Version = "1.0"
    26 	nsStreams = "urn:ietf:params:xml:ns:xmpp-streams"
    28 	nsStreams = "urn:ietf:params:xml:ns:xmpp-streams"
    27 	nsStream = "http://etherx.jabber.org/streams"
    29 	nsStream = "http://etherx.jabber.org/streams"
    28 	nsTLS = "urn:ietf:params:xml:ns:xmpp-tls"
    30 	nsTLS = "urn:ietf:params:xml:ns:xmpp-tls"
    29 	nsSASL = "urn:ietf:params:xml:ns:xmpp-sasl"
    31 	nsSASL = "urn:ietf:params:xml:ns:xmpp-sasl"
    30 	nsBind = "urn:ietf:params:xml:ns:xmpp-bind"
    32 	nsBind = "urn:ietf:params:xml:ns:xmpp-bind"
       
    33 	nsSession = "urn:ietf:params:xml:ns:xmpp-session"
    31 
    34 
    32 	// DNS SRV names
    35 	// DNS SRV names
    33 	serverSrv = "xmpp-server"
    36 	serverSrv = "xmpp-server"
    34 	clientSrv = "xmpp-client"
    37 	clientSrv = "xmpp-client"
    35 
    38 
   216 	}
   219 	}
   217 }
   220 }
   218 
   221 
   219 // This convenience function may be used to generate a unique id for
   222 // This convenience function may be used to generate a unique id for
   220 // use in the Id fields of iq, message, and presence stanzas.
   223 // use in the Id fields of iq, message, and presence stanzas.
       
   224 // BUG(cjyar) This should be replaced with a goroutine that feeds a
       
   225 // channel.
   221 func (cl *Client) NextId() string {
   226 func (cl *Client) NextId() string {
   222 	cl.idMutex.Lock()
   227 	cl.idMutex.Lock()
   223 	defer cl.idMutex.Unlock()
   228 	defer cl.idMutex.Unlock()
   224 	id := cl.nextId
   229 	id := cl.nextId
   225 	cl.nextId++
   230 	cl.nextId++
   226 	return fmt.Sprintf("id_%d", id)
   231 	return fmt.Sprintf("id_%d", id)
   227 }
   232 }
       
   233 
       
   234 // Start an XMPP session. This should typically be done immediately
       
   235 // after creating the new Client. Once the session has been
       
   236 // established, pr will be sent as an initial presence; nil means
       
   237 // don't send initial presence. The initial presence can be a
       
   238 // newly-initialized Presence struct. See RFC 3921, Section 3.
       
   239 func (cl *Client) StartSession(pr *Presence) os.Error {
       
   240 	id := cl.NextId()
       
   241 	iq := &Iq{To: cl.Jid.Domain, Id: id, Type: "set", Any:
       
   242 		&Generic{XMLName: xml.Name{Space: nsSession, Local:
       
   243 				"session"}}}
       
   244 	ch := make(chan os.Error)
       
   245 	f := func(st Stanza) bool {
       
   246 		if st.XType() == "error" {
       
   247 			log.Printf("Can't start session: %v", st)
       
   248 			ch <- st.XError()
       
   249 			return false
       
   250 		}
       
   251 		if pr != nil {
       
   252 			cl.Out <- pr
       
   253 		}
       
   254 		ch <- nil
       
   255 		return false
       
   256 	}
       
   257 	cl.HandleStanza(id, f)
       
   258 	cl.Out <- iq
       
   259 	// Now wait until the callback is called.
       
   260 	return <-ch
       
   261 }