Beispiel #1
0
func (p *protocol) checkOfflineMessage(client *client) {
	var buf bytes.Buffer

	messageIDs, err := model.GetOfflineMessages(client.ClientID)
	if err != nil || messageIDs == nil {
		log.Printf("ERROR: GetOfflineMessages clientID %s error %s ", client.ClientID, err)
		return
	}

	subChannel, _ := strconv.ParseInt(client.SubChannel, 10, 64)
	for _, messageID := range messageIDs {
		msg, err := model.FindMessageByID(messageID)
		if err != nil || msg == nil {
			log.Printf("ERROR: client %s message ID %d message doesn't exist, err %s", client.ClientID, messageID, err)
			continue
		}

		// live := msg.CreatedAt + msg.Expires*100000000000000
		// if time.Now().UnixNano() > live {
		// 	log.Printf("ERROR: client %s message ID %d message expired.", client.ClientID, messageID)
		// 	model.RemoveOfflineMessage(client.ClientID, messageID)
		// 	continue
		// }

		if subChannel != msg.ChannelID {
			continue
		}

		msg2 := &Message{
			Id:        util.Guid(msg.ID).Hex(),
			Body:      []byte(msg.Body),
			Timestamp: msg.CreatedAt,
		}
		log.Printf("msg is %#v", msg2)
		err = p.SendMessage(client, msg2, &buf)
		if err != nil {
			log.Printf("send message to client %s error  %s", client, err)
		}

		client.Lock()
		err = client.Flush()
		client.Unlock()

		log.Printf("send message %#v to client %s success ", msg, client)
		model.RemoveOfflineMessage(client.ClientID, messageID)

	}
}
Beispiel #2
0
func (p *protocol) PUB(client *client, params [][]byte) ([]byte, error) {
	// var err error
	var buf bytes.Buffer
	if client.Role != "$_@push_sign_$_kz_worker" {
		return nil, util.NewFatalClientErr(nil, "E_INVALID_REQUEST", "client can't pub message")
	}

	if len(params) < 3 {
		return nil, util.NewFatalClientErr(nil, "E_INVALID", "PUB insufficient number of parameters")
	}
	log.Printf("receive params on sub  %s", params)

	bodyLen, err := readLen(client.Reader, client.lenSlice)
	if err != nil {
		return nil, util.NewFatalClientErr(err, "E_BAD_BODY", "IDENTIFY failed to read body size")
	}

	if int64(bodyLen) > p.context.broker.options.MaxBodySize {
		return nil, util.NewFatalClientErr(nil, "E_BAD_BODY",
			fmt.Sprintf("IDENTIFY body too big %d > %d", bodyLen, p.context.broker.options.MaxBodySize))
	}

	body := make([]byte, bodyLen)
	_, err = io.ReadFull(client.Reader, body)
	if err != nil {
		return nil, util.NewFatalClientErr(err, "E_BAD_BODY", "IDENTIFY failed to read body")
	}

	client_id := string(params[1])
	channel_id := string(params[2])
	message_id := string(params[3])
	msgId, _ := strconv.ParseInt(message_id, 10, 64)
	log.Printf("msgId ==  %d", msgId)

	// TODO 另外启动一个channel 与 goroutine 用来处理这个消息
	dstClient, err := p.context.broker.GetClient(client_id, channel_id)
	if err != nil || dstClient == nil {
		p.ackPublish(client, util.ACK_OFF, client_id, msgId)
		// model.SaveOfflineMessage(dstClient.ClientID, msgId)
		log.Printf("client %s is null", client_id)
		return nil, nil
		//return nil, util.NewFatalClientErr(nil, "E_INVALID", "PUB insufficient number of parameters")
		// 	return FrameTypeACKError message_id
	}
	log.Printf("get client %s by channel %s = %s  ", client_id, channel_id, dstClient)

	msg := &Message{
		Id:        util.Guid(msgId).Hex(),
		Body:      body,
		Timestamp: time.Now().UnixNano(),
	}
	log.Printf("msg is %#v", msg)
	// dstClient.SendingMessage()
	err = p.SendMessage(dstClient, msg, &buf)
	if err != nil {
		log.Printf("send message to client %s error  %s", dstClient, err)
	}

	dstClient.Lock()
	err = dstClient.Flush()
	dstClient.Unlock()

	if err != nil {
		p.ackPublish(client, util.ACT_ERR, client_id, msgId)
	} else {
		p.ackPublish(client, util.ACK_SUCCESS, client_id, msgId)
	}
	return nil, nil
}