Esempio n. 1
0
func (c *Client) Connect() error {

	conn, err := net.DialTimeout(c.Broker.Type, string(c.Broker.Addr+":"+strconv.Itoa(c.Broker.Port)), c.Broker.TimeOut)

	if err != nil {
		log.Println("Error while TCP connection.")
		log.Println(err)
		return err
	}

	c.Con = conn

	//creating connect message : start.
	m := (Message.NewControlPacket(Message.Connect)).(*Message.ConnectPacket)

	m.ProtocolName = c.ProtocolName
	m.ProtocolVersion = byte(c.ProtocolVersion)
	m.ClientIdentifier = c.Id.(string)

	m.CleanSession = c.CleanSession

	m.WillFlag = c.WillFlag
	m.WillRetain = c.WillRetain

	if c.WillFlag {
		m.WillQos = c.WillQos
		m.WillTopic = c.WillTopic
		m.WillMessage = c.WillPayload
	}

	if c.UserName != "" {
		m.UsernameFlag = true
		m.Username = c.UserName
		//mustn't have password without user as well
		if c.Password != "" {
			m.PasswordFlag = true
			m.Password = []byte(c.Password)
		}
	}

	m.KeepaliveTimer = uint16(c.KeepAlive.Seconds())
	// end.

	if err != m.Write(c.Con) {
		log.Println("Error while writing connect package.")
		log.Println(err)
	}

	//This is the response packet came from server.
	ca, err := Message.ReadPacket(c.Con) //read packet will validate packet and type.

	if err != nil {
		log.Println("Error in receiving.")
		log.Println(err.Error())
		return err
	}

	if ca == nil {
		return errors.New("Received Nil Packet")
	}

	msg, ok := ca.(*Message.ConnackPacket)

	if !ok {
		return errors.New("Received wrong packet.")
	}

	if msg.ReturnCode != Message.Accepted {
		c.Con.Close()
		c.Con = nil
		return errors.New("Wrong Response code.")
	}

	log.Println("Connected...!")

	//connect is done.

	// INIT SETUP : START.
	c.WriteChan = make(chan *PacketAndToken, 100)
	c.ReadChan = make(chan *Message.ControlPacket, 100)
	c.InComingPubChan = make(chan *Message.PublishPacket, 100)
	c.stop = make(chan struct{})

	c.setConnected(true)
	c.HeartBeat.update() // for keep alive.

	c.MessageRouter.matchAndDispatch(c.InComingPubChan, c.Order, c)

	//start contractors.
	go writeContractor(c)
	go readContractor(c)

	if c.KeepAlive > 0 { // if 0 then alive forever. else we need to do some work.
		go keepalive(c)
	}
	//INIT SETUP : DONE
	return nil
}
Esempio n. 2
0
func readContractor(c *Client) {

	c.Workers.Add(1)       // tell client that i am working in your group.
	defer c.Workers.Done() // singnal client that i am done.

	var err error
	var msg Message.ControlPacket

	log.Println("Reader Ready..!")

	for {
		select {
		case <-c.stop:
			return
		default:
			if msg, err = Message.ReadPacket(c.Con); err != nil {
				log.Println("Error in read packet.")
				log.Fatalln(err.Error())
				return
			}

			switch msg.(type) {

			case *Message.PingrespPacket:
				log.Println("Received PingResp")
			case *Message.SubackPacket:

				log.Println("Received SUBACKS")

				sa := msg.(*Message.SubackPacket)
				token := c.getToken(sa.MessageID).(*SubscribeToken)

				//these are the granted Qos From server.
				// for i, qos := range sa.GrantedQoss {
				// 	token.subResult[token.subs[i]] = qos
				// }

				token.flowComplete()   // finish
				c.freeID(sa.MessageID) // free ID.

			case *Message.UnsubackPacket:

				ua := msg.(*Message.UnsubackPacket)
				token := c.getToken(ua.MessageID).(*UnsubscribeToken)
				token.flowComplete()
				c.freeID(ua.MessageID)

			case *Message.PublishPacket: // calls when server publish to this client.

				pp := msg.(*Message.PublishPacket)
				switch pp.Qos {
				case 2:
					c.InComingPubChan <- pp
					pr := Message.NewControlPacket(Message.Pubrec).(*Message.PubrecPacket)
					pr.MessageID = pp.MessageID
					c.WriteChan <- &PacketAndToken{p: pr, t: nil}
				case 1:
					c.InComingPubChan <- pp
					pa := Message.NewControlPacket(Message.Puback).(*Message.PubackPacket)
					pa.MessageID = pp.MessageID
					c.WriteChan <- &PacketAndToken{p: pa, t: nil}
				case 0:
					c.InComingPubChan <- pp
				}

			case *Message.PubackPacket:
				pa := msg.(*Message.PubackPacket)
				c.getToken(pa.MessageID).flowComplete()
				c.freeID(pa.MessageID)

			case *Message.PubrecPacket:
				prec := msg.(*Message.PubrecPacket)
				//log.Println("Received PUBREC")
				prel := Message.NewControlPacket(Message.Pubrel).(*Message.PubrelPacket)
				prel.MessageID = prec.MessageID
				select {
				case c.WriteChan <- &PacketAndToken{p: prel, t: nil}:
				case <-time.After(time.Second):
				}
			case *Message.PubrelPacket:
				pr := msg.(*Message.PubrelPacket)
				pc := Message.NewControlPacket(Message.Pubcomp).(*Message.PubcompPacket)
				pc.MessageID = pr.MessageID
				select {
				case c.WriteChan <- &PacketAndToken{p: pc, t: nil}:
				case <-time.After(time.Second):
				}
			case *Message.PubcompPacket:
				//log.Println("Received PUBCOMP")
				pc := msg.(*Message.PubcompPacket)
				c.getToken(pc.MessageID).flowComplete()
				c.freeID(pc.MessageID)
			}
		}
	}
}