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 } |