xmpp.go
changeset 30 a77fc342e013
parent 29 a456133ed0ac
child 32 4e68d8f89dc3
equal deleted inserted replaced
29:a456133ed0ac 30:a77fc342e013
    55 	authDone bool
    55 	authDone bool
    56 	idMutex sync.Mutex
    56 	idMutex sync.Mutex
    57 	nextId int64
    57 	nextId int64
    58 	handlers chan *stanzaHandler
    58 	handlers chan *stanzaHandler
    59 	inputControl chan int
    59 	inputControl chan int
       
    60 	// This channel may be used as a convenient way to generate a
       
    61 	// unique id for an iq, message, or presence stanza.
       
    62 	Id <-chan string
    60 	// Incoming XMPP stanzas from the server will be published on
    63 	// Incoming XMPP stanzas from the server will be published on
    61 	// this channel. Information which is only used by this
    64 	// this channel. Information which is only used by this
    62 	// library to set up the XMPP stream will not appear here.
    65 	// library to set up the XMPP stream will not appear here.
    63 	In <-chan Stanza
    66 	In <-chan Stanza
    64 	// Outgoing XMPP stanzas to the server should be sent to this
    67 	// Outgoing XMPP stanzas to the server should be sent to this
   106 	cl.password = password
   109 	cl.password = password
   107 	cl.Jid = *jid
   110 	cl.Jid = *jid
   108 	cl.socket = tcp
   111 	cl.socket = tcp
   109 	cl.handlers = make(chan *stanzaHandler, 1)
   112 	cl.handlers = make(chan *stanzaHandler, 1)
   110 	cl.inputControl = make(chan int)
   113 	cl.inputControl = make(chan int)
       
   114 	idCh := make(chan string)
       
   115 	cl.Id = idCh
       
   116 
       
   117 	// Start the unique id generator.
       
   118 	go makeIds(idCh)
   111 
   119 
   112 	// Start the transport handler, initially unencrypted.
   120 	// Start the transport handler, initially unencrypted.
   113 	tlsr, tlsw := cl.startTransport()
   121 	tlsr, tlsw := cl.startTransport()
   114 
   122 
   115 	// Start the reader and writers that convert to and from XML.
   123 	// Start the reader and writers that convert to and from XML.
   217 			f2(ch)
   225 			f2(ch)
   218 		}
   226 		}
   219 	}
   227 	}
   220 }
   228 }
   221 
   229 
   222 // This convenience function may be used to generate a unique id for
   230 func makeIds(ch chan<- string) {
   223 // use in the Id fields of iq, message, and presence stanzas.
   231 	id := int64(1)
   224 // BUG(cjyar) This should be replaced with a goroutine that feeds a
   232 	for {
   225 // channel.
   233 		str := fmt.Sprintf("id_%d", id)
   226 func (cl *Client) NextId() string {
   234 		ch <- str
   227 	cl.idMutex.Lock()
   235 		id++
   228 	defer cl.idMutex.Unlock()
   236 	}
   229 	id := cl.nextId
       
   230 	cl.nextId++
       
   231 	return fmt.Sprintf("id_%d", id)
       
   232 }
   237 }
   233 
   238 
   234 // bindDone is called when we've finished resource binding (and all
   239 // bindDone is called when we've finished resource binding (and all
   235 // the negotiations that precede it). Now we can start accepting
   240 // the negotiations that precede it). Now we can start accepting
   236 // traffic from the app.
   241 // traffic from the app.
   242 // after creating the new Client. Once the session has been
   247 // after creating the new Client. Once the session has been
   243 // established, pr will be sent as an initial presence; nil means
   248 // established, pr will be sent as an initial presence; nil means
   244 // don't send initial presence. The initial presence can be a
   249 // don't send initial presence. The initial presence can be a
   245 // newly-initialized Presence struct. See RFC 3921, Section 3.
   250 // newly-initialized Presence struct. See RFC 3921, Section 3.
   246 func (cl *Client) StartSession(pr *Presence) os.Error {
   251 func (cl *Client) StartSession(pr *Presence) os.Error {
   247 	id := cl.NextId()
   252 	id := <- cl.Id
   248 	iq := &Iq{To: cl.Jid.Domain, Id: id, Type: "set", Any:
   253 	iq := &Iq{To: cl.Jid.Domain, Id: id, Type: "set", Any:
   249 		&Generic{XMLName: xml.Name{Space: nsSession, Local:
   254 		&Generic{XMLName: xml.Name{Space: nsSession, Local:
   250 				"session"}}}
   255 				"session"}}}
   251 	ch := make(chan os.Error)
   256 	ch := make(chan os.Error)
   252 	f := func(st Stanza) bool {
   257 	f := func(st Stanza) bool {