Esempio n. 1
0
// TODO: wanna implement trie. but regexp works well.
// retain should persist their data. though, how do we fetch it efficiently...
func (self *Momonga) RetainMatch(topic string) []*codec.PublishMessage {
	var result []*codec.PublishMessage
	orig := topic

	// TODO: should validate illegal wildcards like /debug/#/hello
	topic = strings.Replace(topic, "+", "[^/]+", -1)
	topic = strings.Replace(topic, "#", ".*", -1)

	reg, err := regexp.Compile(topic)
	if err != nil {
		fmt.Printf("Regexp Error: %s", err)
	}

	all := false
	if string(orig[0:1]) == "#" || string(orig[0:1]) == "+" {
		all = true
	}

	// TODO:これどうにかしたいなー・・・。とは思いつつDBからめて素敵にやるってなるとあんまりいいアイデアない
	itr := self.DataStore.Iterator()
	for ; itr.Valid(); itr.Next() {
		k := string(itr.Key())

		if all && (len(k) > 0 && k[0:1] == "$") {
			// [MQTT-4.7.2-1] The Server MUST NOT match Topic Filters starting with a wildcard character (# or +)
			// with Topic Names beginning with a $ character
			// NOTE: Qlobber doesn't support this feature yet
			continue
		}

		if reg.MatchString(k) {
			data := itr.Value()
			p, _ := codec.ParseMessage(bytes.NewReader(data), 0)
			if v, ok := p.(*codec.PublishMessage); ok {
				result = append(result, v)
			}
		}
	}

	return result
}
Esempio n. 2
0
func (self *MyConnection) ParseMessage() (codec.Message, error) {
	//	self.Mutex.RLock()
	//	defer self.Mutex.RUnlock()

	if self.Keepalive > 0 {
		if cn, ok := self.MyConnection.(net.Conn); ok {
			cn.SetReadDeadline(self.Last.Add(time.Duration(int(float64(self.Keepalive)*1.5)) * time.Second))
		}
	}

	if self.Reader == nil {
		panic("reader is null")
	}

	message, err := codec.ParseMessage(self.Reader, self.MaxMessageSize)
	if err != nil {
		self.logger.Debug(">>> Message: %s\n", err)
		if v, ok := self.Events["error"].(func(error)); ok {
			v(err)
		}
		return nil, err
	}

	self.logger.Debug("Read Message: [%s] %+v", message.GetTypeAsString(), message)
	if v, ok := self.Events["parsed"]; ok {
		if cb, ok := v.(func()); ok {
			cb()
		}
	}

	// 以下callbackを呼ぶだけのコード
	switch message.GetType() {
	case codec.PACKET_TYPE_PUBLISH:
		p := message.(*codec.PublishMessage)
		if v, ok := self.Events["publish"]; ok {
			if cb, ok := v.(func(*codec.PublishMessage)); ok {
				cb(p)
			}
		}
		break

	case codec.PACKET_TYPE_CONNACK:
		p := message.(*codec.ConnackMessage)
		if v, ok := self.Events["connack"]; ok {
			if cb, ok := v.(func(uint8)); ok {
				cb(p.ReturnCode)
			}
		}
		break

	case codec.PACKET_TYPE_PUBACK:
		p := message.(*codec.PubackMessage)
		if v, ok := self.Events["puback"]; ok {
			if cb, ok := v.(func(uint16)); ok {
				cb(p.PacketIdentifier)
			}
		}
		break

	case codec.PACKET_TYPE_PUBREC:
		p := message.(*codec.PubrecMessage)
		if v, ok := self.Events["pubrec"]; ok {
			if cb, ok := v.(func(uint16)); ok {
				cb(p.PacketIdentifier)
			}
		}
		break

	case codec.PACKET_TYPE_PUBREL:
		// PUBRELを受けるということはReceiverとして受けるということ
		p := message.(*codec.PubrelMessage)
		if v, ok := self.Events["pubrel"]; ok {
			if cb, ok := v.(func(uint16)); ok {
				cb(p.PacketIdentifier)
			}
		}
		break

	case codec.PACKET_TYPE_PUBCOMP:
		// PUBCOMPを受けるということはSenderとして受けるということ。
		p := message.(*codec.PubcompMessage)
		if v, ok := self.Events["pubcomp"]; ok {
			if cb, ok := v.(func(uint16)); ok {
				cb(p.PacketIdentifier)
			}
		}
		break

	case codec.PACKET_TYPE_PINGREQ:
		if v, ok := self.Events["pingreq"]; ok {
			if cb, ok := v.(func()); ok {
				cb()
			}
		}
		break

	case codec.PACKET_TYPE_PINGRESP:
		if v, ok := self.Events["pingresp"]; ok {
			if cb, ok := v.(func()); ok {
				cb()
			}
		}
		break

	case codec.PACKET_TYPE_SUBACK:
		p := message.(*codec.SubackMessage)
		if v, ok := self.Events["suback"]; ok {
			if cb, ok := v.(func(uint16, int)); ok {
				cb(p.PacketIdentifier, 0)
			}
		}
		break

	case codec.PACKET_TYPE_UNSUBACK:
		p := message.(*codec.UnsubackMessage)
		if v, ok := self.Events["unsuback"]; ok {
			if cb, ok := v.(func(uint16)); ok {
				cb(p.PacketIdentifier)
			}
		}
		break

	case codec.PACKET_TYPE_CONNECT:
		p := message.(*codec.ConnectMessage)
		if v, ok := self.Events["connect"]; ok {
			if cb, ok := v.(func(*codec.ConnectMessage)); ok {
				cb(p)
			}
		}
		break

	case codec.PACKET_TYPE_SUBSCRIBE:
		p := message.(*codec.SubscribeMessage)
		if v, ok := self.Events["subscribe"]; ok {
			if cb, ok := v.(func(*codec.SubscribeMessage)); ok {
				cb(p)
			}
		}
		break
	case codec.PACKET_TYPE_DISCONNECT:
		if v, ok := self.Events["disconnect"]; ok {
			if cb, ok := v.(func()); ok {
				cb()
			}
		}
		break
	case codec.PACKET_TYPE_UNSUBSCRIBE:
		p := message.(*codec.UnsubscribeMessage)
		if v, ok := self.Events["unsubscribe"]; ok {
			if cb, ok := v.(func(uint16, int, []codec.SubscribePayload)); ok {
				cb(p.PacketIdentifier, 0, p.Payload)
			}
		}
		break
	default:
		self.logger.Error("Unhandled message: %+v\n", message)
	}

	self.invalidateTimer()
	self.Last = time.Now()
	return message, err
}