// Start a pack write queue // It should run in a new grountine func (queue *PackQueue) writeLoop() { // defer recover() var err error loop: for { select { case pt := <-queue.writeChan: if pt == nil { break loop } if Conf.WriteTimeout > 0 { queue.conn.SetWriteDeadline(time.Now().Add(time.Second * time.Duration(Conf.WriteTimeout))) } switch pt.typ { case NO_DELAY: err = mqtt.WritePack(pt.pack, queue.w) case DELAY: err = mqtt.DelayWritePack(pt.pack, queue.w) case FLUSH: err = queue.w.Flush() } if err != nil { // Tell listener the error queue.writeError = err break loop } } } // Notice the read if err != nil { queue.errorChan <- err } }
// Do login check and response or push func (c *conn) serve() { var err error defer func() { if err := recover(); err != nil { buff := make([]byte, 4096) runtime.Stack(buff, false) glog.Errorf("conn.serve() panic(%v)\n info:%s", err, string(buff)) } c.rw.Close() }() var l listener if l, err = login(c.r, c.w, c.rw, c.typ); err != nil { glog.Errorf("Login error :%v\n", err) return } err = mqtt.WritePack(mqtt.GetConnAckPack(0), c.w) if err != nil { return } l.listen_loop() }