Beispiel #1
0
func (q *MsgQueue) fetchMsg() {
	log.Info("fetch")
	conn, err := amqp.Dial(Conf.AMQPUrl)
	if err != nil {
		log.Error("Failed to connect to RabbitMQ", err)
		return
	}
	defer conn.Close()

	ch, err := conn.Channel()
	if err != nil {
		log.Error("Failed to open a channel", err)
		return
	}
	defer ch.Close()

	qu, err := ch.QueueDeclare(
		Conf.ACSQueue, // name
		false,         // durable
		false,         // delete when unused
		false,         // exclusive
		false,         // no-wait
		nil,           // arguments
	)
	if err != nil {
		log.Error("Failed to declare a queue ", err)
		return
	}

	err = ch.Qos(
		1,     // prefetch count
		0,     // prefetch size
		false, // global
	)
	if err != nil {
		log.Error("Failed to set QoS", err)
		return
	}

	msgs, err := ch.Consume(
		qu.Name, // queue
		"",      // consumer
		false,   // auto-ack
		false,   // exclusive
		false,   // no-local
		false,   // no-wait
		nil,     // args
	)
	if err != nil {
		log.Error("Failed to register a consumer", err)
		return
	}
	forever := make(chan bool)
	go func(flag chan bool) {
		log.Error("closing", <-conn.NotifyClose(make(chan *amqp.Error)))
		flag <- true
	}(forever)
	go func() {
		for deliver := range msgs {
			if Debug {
				log.Debug("Received a message: %s", deliver.Body)
				log.Debug("Received a message replyTo: %s", deliver.ReplyTo)
			}
			deliver.Ack(false)
			if deliver.Headers["DeviceID"] != nil {
				sn := deliver.Headers["DeviceID"].(string)
				msg := Message{
					MessageProperties: MessageProperties{
						Headers:         deliver.Headers,
						CorrelationID:   deliver.CorrelationId,
						ReplyTo:         deliver.ReplyTo,
						ContentEncoding: deliver.ContentEncoding,
						ContentType:     deliver.ContentType,
					},
					Body: deliver.Body,
				}
				//q.Push(sn, msg)
				var channel *Channel
				if channel = DefaultBucket.Channel(sn); channel != nil { //根据sub key找到user对应的channel
					err := channel.Push(msg.MessageProperties, msg.Body)
					if err != nil {
						log.Warn("push msg into %s ch err:%s", sn, err)
					}
				} else {
					//new channel
					channel = NewChannel(Conf.RingSize)
					err := channel.Push(msg.MessageProperties, msg.Body)
					if err != nil {
						log.Warn("push msg into %s new ch err:%s", sn, err)
					}
					DefaultBucket.Put(sn, channel)
				}
				//send to stun
				//dot_count := bytes.Count(d.Body, []byte("."))
				//t := time.Duration(dot_count)
				//time.Sleep(t * time.Second)
				//models.Kick(sn)
				SendText(sn, "stun_queue")
			}
		}
	}()

	<-forever
}
Beispiel #2
0
func tr069(w http.ResponseWriter, r *http.Request) {
	var requestBody []byte
	var err error
	if r.Method == "POST" {
		// receive posted data
		requestBody, err = ioutil.ReadAll(r.Body)
		if err != nil {
			log.Warn("tr069 read body error(%v)", err)
		}
	}

	var response []byte
	cpeSentEmptyReq := true
	var sn string
	if len(requestBody) > 0 {
		cpeSentEmptyReq = false
		msg, err := messages.ParseXML(requestBody)
		if err == nil {
			switch msg.GetName() {
			case "Inform":
				curInform := msg.(*messages.Inform)
				sn = curInform.Sn
				globalSessions.Put(w, r, sn)
				//response
				resp := new(messages.InformResponse)
				resp.MaxEnvelopes = maxEnvelopes
				response = resp.CreateXML()
				if curInform.IsEvent(messages.EventPeriodic) {
					//TODO
					//sync device info
				} else if curInform.IsEvent(messages.EventValueChange) {
					//TODO
					//sync config
				}
			case "TransferComplete":
				tc := msg.(*messages.TransferComplete)
				resp := new(messages.TransferCompleteResponse)
				resp.ID = tc.ID
				//TODO
				//rpc reply
				response = resp.CreateXML()
			case "GetRPCMethods":
				gm := msg.(*messages.GetRPCMethods)
				resp := new(messages.GetRPCMethodsResponse)
				resp.ID = gm.ID
				response = resp.CreateXML()
			default:
				//rpc reply
				//read replyto and send reponse msg to mq
				//TODO
				//根据sessionid读取replytTo,corrID,session需要保证replyTo的一致性,不是每条消息都有replyTo
				session := globalSessions.Get(w, r)
				if session != nil {
					//sn := session.SN
					if len(session.ReplyTo) > 0 {
						//send rpc reply
						sendRPCResponse(msg, session.ReplyTo, session.CorrelationID)
					}
					//has msg anymore
					var channel *Channel
					if channel = DefaultBucket.Channel(session.SN); channel != nil {
						//read msg
						var msg *Message
						var err error
						if msg, err = channel.SvrProto.Get(); err != nil {
							// must be empty error
							err = nil
							session.ReplyTo = ""
							session.CorrelationID = ""
						} else {
							// just forward the message
							if Debug {
								log.Debug("channel msg:", string(msg.Body))
							}
							m := FromMessage(*msg)
							session.ReplyTo = msg.ReplyTo
							session.CorrelationID = msg.CorrelationID
							response = m.CreateXML()
							channel.SvrProto.GetAdv() //读计算器累加
						}
					} else {
						session.ReplyTo = ""
						session.CorrelationID = ""
					}
				}

			}
		}
	}

	if cpeSentEmptyReq {
		session := globalSessions.Get(w, r)
		if session != nil {
			//根据sn取消息
			var channel *Channel
			if channel = DefaultBucket.Channel(session.SN); channel != nil {
				//read msg
				var msg *Message
				var err error
				if msg, err = channel.SvrProto.Get(); err != nil {
					// must be empty error
					err = nil
					session.ReplyTo = ""
					session.CorrelationID = ""
				} else {
					// just forward the message
					if Debug {
						log.Debug("channel msg:", string(msg.Body))
					}
					m := FromMessage(*msg)
					session.ReplyTo = msg.ReplyTo
					session.CorrelationID = msg.CorrelationID
					response = m.CreateXML()
					channel.SvrProto.GetAdv() //读计算器累加
				}
			} else {
				session.ReplyTo = ""
				session.CorrelationID = ""
			}
		}
	}
	//write response
	w.Header().Add("Content-Type", "application/xml; charset=utf-8")
	w.Header().Set("Content-Length", strconv.Itoa(len(response)))
	w.Write(response)
}