core: Handle message acknowledgement and time deltas

Depending on further changes to go-ricochet, which are submitted
upstream and imported here as usual.
This commit is contained in:
John Brooks 2017-09-25 13:24:10 -07:00
parent 1ac9e4f065
commit 5475eeddba
6 changed files with 40 additions and 33 deletions

View File

@ -136,9 +136,7 @@ func (c *Conversation) Send(text string) (*ricochet.Message, error) {
message.Status = ricochet.Message_QUEUED message.Status = ricochet.Message_QUEUED
} }
} else { } else {
// XXX go-ricochet doesn't support message IDs & ack properly yet, so skip SENDING message.Status = ricochet.Message_SENDING
//message.Status = ricochet.Message_SENDING
message.Status = ricochet.Message_DELIVERED
} }
c.messages = append(c.messages, message) c.messages = append(c.messages, message)
@ -177,9 +175,7 @@ func (c *Conversation) SendQueuedMessages() int {
break break
} }
} else { } else {
// XXX go-ricochet doesn't support message IDs & ack properly yet, so skip SENDING message.Status = ricochet.Message_SENDING
//message.Status = ricochet.Message_SENDING
message.Status = ricochet.Message_DELIVERED
sent++ sent++
} }
@ -229,11 +225,10 @@ func (c *Conversation) ChatMessage(messageID uint32, when time.Time, message str
return true return true
} }
func (c *Conversation) ChatMessageAck(messageID uint32) { func (c *Conversation) ChatMessageAck(messageID uint32, accepted bool) {
// XXX no success field log.Printf("chat ack: %d %v", messageID, accepted)
log.Printf("chat ack: %d", messageID)
c.UpdateSentStatus(uint64(messageID), true) c.UpdateSentStatus(uint64(messageID), accepted)
} }
func (c *Conversation) sendMessageToConnection(message *ricochet.Message) (connected bool, err error) { func (c *Conversation) sendMessageToConnection(message *ricochet.Message) (connected bool, err error) {
@ -259,8 +254,11 @@ func (c *Conversation) sendMessageToConnection(message *ricochet.Message) (conne
return errors.New("invalid chat channel") return errors.New("invalid chat channel")
} }
// XXX message id and all of that // Set message.Timestamp now if unset
chat.SendMessage(message.Text) if message.Timestamp == 0 {
message.Timestamp = time.Now().Unix()
}
message.Identifier = uint64(chat.SendMessageWithTime(message.Text, time.Unix(message.Timestamp, 0)))
return nil return nil
}) })

View File

@ -60,7 +60,7 @@ func (rai *RicochetApplicationInstance) ChatMessage(messageID uint32, when time.
return true return true
} }
func (rai *RicochetApplicationInstance) ChatMessageAck(messageID uint32) { func (rai *RicochetApplicationInstance) ChatMessageAck(messageID uint32, accepted bool) {
rai.ChatMessageAckHandler(rai, messageID) rai.ChatMessageAckHandler(rai, messageID)
} }

View File

@ -35,22 +35,34 @@ type ChatChannelHandler interface {
// the message successfully, and false to NACK and refuse the message. // the message successfully, and false to NACK and refuse the message.
ChatMessage(messageID uint32, when time.Time, message string) bool ChatMessage(messageID uint32, when time.Time, message string) bool
// ChatMessageAck is called when an acknowledgement of a sent message is received. // ChatMessageAck is called when an acknowledgement of a sent message is received.
ChatMessageAck(messageID uint32) ChatMessageAck(messageID uint32, accepted bool)
} }
// SendMessage sends a given message using this channe // SendMessage sends a given message using this channel, and returns the
func (cc *ChatChannel) SendMessage(message string) { // messageID, which will be used in ChatMessageAck when the peer acknowledges
// this message.
func (cc *ChatChannel) SendMessage(message string) uint32 {
return cc.SendMessageWithTime(message, time.Now())
}
// SendMessageWithTime is identical to SendMessage, but also sends the provided time.Time
// as a rough timestamp for when this message was originally sent. This should be used
// when retrying or sending queued messages.
func (cc *ChatChannel) SendMessageWithTime(message string, when time.Time) uint32 {
delta := time.Now().Sub(when) / time.Second
messageBuilder := new(utils.MessageBuilder) messageBuilder := new(utils.MessageBuilder)
//TODO Implement Chat Number messageID := cc.lastMessageID
data := messageBuilder.ChatMessage(message, cc.lastMessageID)
cc.lastMessageID++ cc.lastMessageID++
data := messageBuilder.ChatMessage(message, messageID, int64(delta))
cc.channel.SendMessage(data) cc.channel.SendMessage(data)
return messageID
} }
// Acknowledge indicates the given messageID was received // Acknowledge indicates that the given messageID was received, and whether
func (cc *ChatChannel) Acknowledge(messageID uint32) { // it was accepted.
func (cc *ChatChannel) Acknowledge(messageID uint32, accepted bool) {
messageBuilder := new(utils.MessageBuilder) messageBuilder := new(utils.MessageBuilder)
cc.channel.SendMessage(messageBuilder.AckChatMessage(messageID)) cc.channel.SendMessage(messageBuilder.AckChatMessage(messageID, accepted))
} }
// Type returns the type string for this channel, e.g. "im.ricochet.chat". // Type returns the type string for this channel, e.g. "im.ricochet.chat".
@ -132,13 +144,9 @@ func (cc *ChatChannel) Packet(data []byte) {
if err == nil { if err == nil {
if res.GetChatMessage() != nil { if res.GetChatMessage() != nil {
ack := cc.Handler.ChatMessage(res.GetChatMessage().GetMessageId(), time.Now(), res.GetChatMessage().GetMessageText()) ack := cc.Handler.ChatMessage(res.GetChatMessage().GetMessageId(), time.Now(), res.GetChatMessage().GetMessageText())
if ack { cc.Acknowledge(res.GetChatMessage().GetMessageId(), ack)
cc.Acknowledge(res.GetChatMessage().GetMessageId()) } else if ack := res.GetChatAcknowledge(); ack != nil {
} else { cc.Handler.ChatMessageAck(ack.GetMessageId(), ack.GetAccepted())
//XXX
}
} else if res.GetChatAcknowledge() != nil {
cc.Handler.ChatMessageAck(res.GetChatMessage().GetMessageId())
} }
// XXX? // XXX?
} }

View File

@ -32,7 +32,7 @@ func (echobot *RicochetEchoBot) ChatMessage(messageID uint32, when time.Time, me
return true return true
} }
func (echobot *RicochetEchoBot) ChatMessageAck(messageID uint32) { func (echobot *RicochetEchoBot) ChatMessageAck(messageID uint32, accepted bool) {
} }

View File

@ -195,10 +195,11 @@ func (mb *MessageBuilder) AuthResult(accepted bool, isKnownContact bool) []byte
} }
// ChatMessage constructs a chat message with the given content. // ChatMessage constructs a chat message with the given content.
func (mb *MessageBuilder) ChatMessage(message string, messageID uint32) []byte { func (mb *MessageBuilder) ChatMessage(message string, messageID uint32, timeDelta int64) []byte {
cm := &Protocol_Data_Chat.ChatMessage{ cm := &Protocol_Data_Chat.ChatMessage{
MessageId: proto.Uint32(messageID), MessageId: proto.Uint32(messageID),
MessageText: proto.String(message), MessageText: proto.String(message),
TimeDelta: proto.Int64(timeDelta),
} }
chatPacket := &Protocol_Data_Chat.Packet{ chatPacket := &Protocol_Data_Chat.Packet{
ChatMessage: cm, ChatMessage: cm,
@ -209,10 +210,10 @@ func (mb *MessageBuilder) ChatMessage(message string, messageID uint32) []byte {
} }
// AckChatMessage constructs a chat message acknowledgement. // AckChatMessage constructs a chat message acknowledgement.
func (mb *MessageBuilder) AckChatMessage(messageID uint32) []byte { func (mb *MessageBuilder) AckChatMessage(messageID uint32, accepted bool) []byte {
cr := &Protocol_Data_Chat.ChatAcknowledge{ cr := &Protocol_Data_Chat.ChatAcknowledge{
MessageId: proto.Uint32(messageID), MessageId: proto.Uint32(messageID),
Accepted: proto.Bool(true), Accepted: proto.Bool(accepted),
} }
pc := &Protocol_Data_Chat.Packet{ pc := &Protocol_Data_Chat.Packet{
ChatAcknowledge: cr, ChatAcknowledge: cr,

2
vendor/manifest vendored
View File

@ -63,7 +63,7 @@
"importpath": "github.com/s-rah/go-ricochet", "importpath": "github.com/s-rah/go-ricochet",
"repository": "https://github.com/special/go-ricochet-protocol", "repository": "https://github.com/special/go-ricochet-protocol",
"vcs": "git", "vcs": "git",
"revision": "5b54d50bf4611a36c23dd732bd1e9d0dad441980", "revision": "e5211eec18a2b58d379e232088154925439a74c0",
"branch": "api-rework-fixes", "branch": "api-rework-fixes",
"notests": true "notests": true
}, },