package sessions import ( "fmt" "sync" "github.com/eclipse/paho.mqtt.golang/packets" ) const ( // Queue size for the ack queue defaultQueueSize = 16 ) type Session struct { // cmsg is the CONNECT message cmsg *packets.ConnectPacket // Will message to publish if connect is closed unexpectedly Will *packets.PublishPacket // Retained publish message Retained *packets.PublishPacket // topics stores all the topis for this session/client topics map[string]byte // Initialized? initted bool // Serialize access to this session mu sync.Mutex id string } func (this *Session) Init(msg *packets.ConnectPacket) error { this.mu.Lock() defer this.mu.Unlock() if this.initted { return fmt.Errorf("Session already initialized") } this.cmsg = msg if this.cmsg.WillFlag { this.Will = packets.NewControlPacket(packets.Publish).(*packets.PublishPacket) this.Will.Qos = this.cmsg.Qos this.Will.TopicName = this.cmsg.WillTopic this.Will.Payload = this.cmsg.WillMessage this.Will.Retain = this.cmsg.WillRetain } this.topics = make(map[string]byte, 1) this.id = string(msg.ClientIdentifier) this.initted = true return nil } func (this *Session) Update(msg *packets.ConnectPacket) error { this.mu.Lock() defer this.mu.Unlock() this.cmsg = msg return nil } func (this *Session) RetainMessage(msg *packets.PublishPacket) error { this.mu.Lock() defer this.mu.Unlock() this.Retained = msg return nil } func (this *Session) AddTopic(topic string, qos byte) error { this.mu.Lock() defer this.mu.Unlock() if !this.initted { return fmt.Errorf("Session not yet initialized") } this.topics[topic] = qos return nil } func (this *Session) RemoveTopic(topic string) error { this.mu.Lock() defer this.mu.Unlock() if !this.initted { return fmt.Errorf("Session not yet initialized") } delete(this.topics, topic) return nil } func (this *Session) Topics() ([]string, []byte, error) { this.mu.Lock() defer this.mu.Unlock() if !this.initted { return nil, nil, fmt.Errorf("Session not yet initialized") } var ( topics []string qoss []byte ) for k, v := range this.topics { topics = append(topics, k) qoss = append(qoss, v) } return topics, qoss, nil } func (this *Session) ID() string { return this.cmsg.ClientIdentifier } func (this *Session) WillFlag() bool { this.mu.Lock() defer this.mu.Unlock() return this.cmsg.WillFlag } func (this *Session) SetWillFlag(v bool) { this.mu.Lock() defer this.mu.Unlock() this.cmsg.WillFlag = v } func (this *Session) CleanSession() bool { this.mu.Lock() defer this.mu.Unlock() return this.cmsg.CleanSession }