// Get a read pack queue // Only call once func (queue *PackQueue) ReadPackInLoop(fin <-chan byte) <-chan *packAndErr { ch := make(chan *packAndErr, Conf.ReadPackLoop) go func() { // defer recover() is_continue := true p := new(packAndErr) loop: for { if queue.alive > 0 { queue.conn.SetReadDeadline(time.Now().Add(time.Second * time.Duration(queue.alive))) } if is_continue { p.pack, p.err = mqtt.ReadPack(queue.r) if p.err != nil { is_continue = false } select { case ch <- p: // Without anything to do case <-fin: glog.Info("Queue FIN") break loop } } else { <-fin glog.Info("Queue FIN") break loop } p = new(packAndErr) } close(ch) }() return ch }
// Read a pack and retuen the write queue error func (queue *PackQueue) ReadPack() (pack *mqtt.Pack, err error) { go func() { p := new(packAndErr) if Conf.ReadTimeout > 0 { queue.conn.SetReadDeadline(time.Now().Add(time.Second * time.Duration(Conf.ReadTimeout))) } p.pack, p.err = mqtt.ReadPack(queue.r) queue.readChan <- p }() select { case err = <-queue.errorChan: // Hava an error // pass case pAndErr := <-queue.readChan: pack = pAndErr.pack err = pAndErr.err } return }
func login(r *bufio.Reader, w *bufio.Writer, conn net.Conn, typ int) (l listener, err error) { var pack *mqtt.Pack pack, err = mqtt.ReadPack(r) if err != nil { glog.Error("Read login pack error") return } if pack.GetType() != mqtt.CONNECT { err = fmt.Errorf("Recive login pack's type error:%v \n", pack.GetType()) return } info, ok := (pack.GetVariable()).(*mqtt.Connect) if !ok { err = errors.New("It's not a mqtt connection package.") return } id := info.GetUserName() psw := info.GetPassword() switch typ { case CLIENT: if !store.Manager.Client_login(*id, *psw) { err = fmt.Errorf("Client Authentication is not passed id:%v,psw:%v", *id, *psw) break } // Has been already logon // TODO var ( ok bool s string ) re: ok, s, err = redis.IsExist(*id) if err != nil { return } if ok { var client *rpc.Client client, err = rpc.DialHTTP("tcp", s) if err != nil { return } reply := new(myrpc.Reply) err = client.Call("Comet_RPC.Relogin", *id, reply) if err != nil { return } if reply.IsRe { goto re } if !reply.IsOk { err = errors.New("Has been relogining") return } } c := newClient(r, w, conn, *id, info.GetKeepAlive()) // Redis Append. if err = redis.Login(*id, Conf.RPC_addr); err != nil { return } Users.Set(*id, c) l = c case CSERVER: // TODO default: fmt.Errorf("No such pack type :%v", typ) } return }