roster.go
changeset 110 7696e6a01709
parent 98 c9cc4eda6dce
child 111 36287f2cf06e
equal deleted inserted replaced
109:3887d7ad19c1 110:7696e6a01709
    46 // that information. This is called once from a fairly deep call stack
    46 // that information. This is called once from a fairly deep call stack
    47 // as part of XMPP negotiation.
    47 // as part of XMPP negotiation.
    48 func fetchRoster(client *Client) error {
    48 func fetchRoster(client *Client) error {
    49 	rosterUpdate := rosterClients[client.Uid].rosterUpdate
    49 	rosterUpdate := rosterClients[client.Uid].rosterUpdate
    50 
    50 
    51 	iq := &Iq{From: client.Jid.String(), Id: <-Id, Type: "get",
    51 	iq := &Iq{Stanza: Stanza{From: client.Jid.String(), Type: "get",
    52 		Nested: []interface{}{RosterQuery{}}}
    52 		Id: <-Id, Nested: []interface{}{RosterQuery{}}}}
    53 	ch := make(chan error)
    53 	ch := make(chan error)
    54 	f := func(st Stanza) bool {
    54 	f := func(v interface{}) bool {
    55 		defer close(ch)
    55 		defer close(ch)
    56 		iq, ok := st.(*Iq)
    56 		iq, ok := v.(*Iq)
    57 		if !ok {
    57 		if !ok {
    58 			ch <- fmt.Errorf("response to iq wasn't iq: %s", st)
    58 			ch <- fmt.Errorf("response to iq wasn't iq: %s", v)
    59 			return false
    59 			return false
    60 		}
    60 		}
    61 		if iq.Type == "error" {
    61 		if iq.Type == "error" {
    62 			ch <- iq.Error
    62 			ch <- iq.Error
    63 			return false
    63 			return false
    69 				break
    69 				break
    70 			}
    70 			}
    71 		}
    71 		}
    72 		if rq == nil {
    72 		if rq == nil {
    73 			ch <- fmt.Errorf(
    73 			ch <- fmt.Errorf(
    74 				"Roster query result not query: %v", st)
    74 				"Roster query result not query: %v", v)
    75 			return false
    75 			return false
    76 		}
    76 		}
    77 		for _, item := range rq.Item {
    77 		for _, item := range rq.Item {
    78 			rosterUpdate <- item
    78 			rosterUpdate <- item
    79 		}
    79 		}
    89 // The roster filter updates the Client's representation of the
    89 // The roster filter updates the Client's representation of the
    90 // roster, but it lets the relevant stanzas through. This also starts
    90 // roster, but it lets the relevant stanzas through. This also starts
    91 // the roster feeder, which is the goroutine that provides data on
    91 // the roster feeder, which is the goroutine that provides data on
    92 // client.Roster.
    92 // client.Roster.
    93 func startRosterFilter(client *Client) {
    93 func startRosterFilter(client *Client) {
    94 	out := make(chan Stanza)
    94 	out := make(chan interface{})
    95 	in := client.AddFilter(out)
    95 	in := client.AddFilter(out)
    96 	go func(in <-chan Stanza, out chan<- Stanza) {
    96 	go func(in <-chan interface{}, out chan<- interface{}) {
    97 		defer close(out)
    97 		defer close(out)
    98 		for st := range in {
    98 		for st := range in {
    99 			maybeUpdateRoster(client, st)
    99 			maybeUpdateRoster(client, st)
   100 			out <- st
   100 			out <- st
   101 		}
   101 		}
   106 	rosterClients[client.Uid] = rosterClient{rosterChan: rosterCh,
   106 	rosterClients[client.Uid] = rosterClient{rosterChan: rosterCh,
   107 		rosterUpdate: rosterUpdate}
   107 		rosterUpdate: rosterUpdate}
   108 	go feedRoster(rosterCh, rosterUpdate)
   108 	go feedRoster(rosterCh, rosterUpdate)
   109 }
   109 }
   110 
   110 
   111 func maybeUpdateRoster(client *Client, st Stanza) {
   111 func maybeUpdateRoster(client *Client, st interface{}) {
   112 	iq, ok := st.(*Iq)
   112 	iq, ok := st.(*Iq)
   113 	if !ok {
   113 	if !ok {
   114 		return
   114 		return
   115 	}
   115 	}
   116 
   116 
   126 	if iq.Type == "set" && rq != nil {
   126 	if iq.Type == "set" && rq != nil {
   127 		for _, item := range rq.Item {
   127 		for _, item := range rq.Item {
   128 			rosterUpdate <- item
   128 			rosterUpdate <- item
   129 		}
   129 		}
   130 		// Send a reply.
   130 		// Send a reply.
   131 		reply := &Iq{To: iq.From, Id: iq.Id, Type: "result"}
   131 		reply := &Iq{Stanza: Stanza{To: iq.From, Id: iq.Id,
       
   132 			Type: "result"}}
   132 		client.Out <- reply
   133 		client.Out <- reply
   133 	}
   134 	}
   134 }
   135 }
   135 
   136 
   136 func feedRoster(rosterCh chan<- []RosterItem, rosterUpdate <-chan RosterItem) {
   137 func feedRoster(rosterCh chan<- []RosterItem, rosterUpdate <-chan RosterItem) {