Implement conversation with the new protocol API
Conversation now acts as a ChatChannelHandler, so a Conversation is able to directly recieve messages on the associated ChatChannel.
This commit is contained in:
parent
0c187e72a0
commit
0b19ae4b66
|
@ -3,8 +3,6 @@ package core
|
|||
import (
|
||||
"github.com/s-rah/go-ricochet/channels"
|
||||
"github.com/s-rah/go-ricochet/connection"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ContactProtocolHandler struct {
|
||||
|
@ -18,32 +16,14 @@ func NewContactProtocolHandler(contact *Contact, conn *connection.Connection) *C
|
|||
conn: conn,
|
||||
contact: contact,
|
||||
}
|
||||
handler.Init(nil, conn.RemoteHostname)
|
||||
handler.Init()
|
||||
|
||||
handler.RegisterChannelHandler("im.ricochet.chat", func() channels.Handler {
|
||||
chat := new(channels.ChatChannel)
|
||||
chat.Handler = handler
|
||||
chat := &channels.ChatChannel{
|
||||
Handler: contact.Conversation(),
|
||||
}
|
||||
return chat
|
||||
})
|
||||
|
||||
// XXX Somebody needs to be calling Process, nobody is yet, need that rework in contact
|
||||
return handler
|
||||
}
|
||||
|
||||
// Implement ChatChannelHandler for im.ricochet.chat
|
||||
func (handler *ContactProtocolHandler) ChatMessage(messageID uint32, when time.Time, message string) bool {
|
||||
// XXX sanity checks, message contents, etc
|
||||
log.Printf("chat message: %d %d %v %s", messageID, when, message)
|
||||
|
||||
conversation := handler.contact.Conversation()
|
||||
conversation.Receive(uint64(messageID), when.Unix(), message)
|
||||
return true
|
||||
}
|
||||
|
||||
func (handler *ContactProtocolHandler) ChatMessageAck(messageID uint32) {
|
||||
// XXX no success field
|
||||
log.Printf("chat ack: %d", messageID)
|
||||
|
||||
conversation := handler.contact.Conversation()
|
||||
conversation.UpdateSentStatus(uint64(messageID), true)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"errors"
|
||||
"github.com/ricochet-im/ricochet-go/core/utils"
|
||||
"github.com/ricochet-im/ricochet-go/rpc"
|
||||
connection "github.com/s-rah/go-ricochet/connection"
|
||||
"github.com/s-rah/go-ricochet/channels"
|
||||
"log"
|
||||
"math/rand"
|
||||
"sync"
|
||||
|
@ -129,10 +129,13 @@ func (c *Conversation) Send(text string) (*ricochet.Message, error) {
|
|||
Text: text,
|
||||
}
|
||||
|
||||
// XXX threading mess, and probably deadlockable. Need better API for conn.
|
||||
conn := c.Contact.Connection()
|
||||
if conn != nil {
|
||||
sendMessageToConnection(conn, message)
|
||||
if online, err := c.sendMessageToConnection(message); err != nil {
|
||||
if online {
|
||||
message.Status = ricochet.Message_ERROR
|
||||
} else {
|
||||
message.Status = ricochet.Message_QUEUED
|
||||
}
|
||||
} else {
|
||||
// XXX go-ricochet doesn't support message IDs & ack properly yet, so skip SENDING
|
||||
//message.Status = ricochet.Message_SENDING
|
||||
message.Status = ricochet.Message_DELIVERED
|
||||
|
@ -166,11 +169,19 @@ func (c *Conversation) SendQueuedMessages() int {
|
|||
continue
|
||||
}
|
||||
|
||||
sendMessageToConnection(conn, message)
|
||||
// XXX go-ricochet doesn't support message IDs & ack properly yet, so skip SENDING
|
||||
//message.Status = ricochet.Message_SENDING
|
||||
message.Status = ricochet.Message_DELIVERED
|
||||
sent++
|
||||
if online, err := c.sendMessageToConnection(message); err != nil {
|
||||
if online {
|
||||
message.Status = ricochet.Message_ERROR
|
||||
} else {
|
||||
// Offline again?
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// XXX go-ricochet doesn't support message IDs & ack properly yet, so skip SENDING
|
||||
//message.Status = ricochet.Message_SENDING
|
||||
message.Status = ricochet.Message_DELIVERED
|
||||
sent++
|
||||
}
|
||||
|
||||
event := ricochet.ConversationEvent{
|
||||
Type: ricochet.ConversationEvent_UPDATE,
|
||||
|
@ -182,25 +193,6 @@ func (c *Conversation) SendQueuedMessages() int {
|
|||
return sent
|
||||
}
|
||||
|
||||
func sendMessageToConnection(conn *connection.Connection, message *ricochet.Message) {
|
||||
// XXX
|
||||
panic("sendMessageToConnection needs implementing for new protocol API")
|
||||
/*
|
||||
// XXX hardcoded channel IDs, also channel IDs shouldn't be exposed
|
||||
channelId := int32(7)
|
||||
if conn.IsInbound {
|
||||
channelId++
|
||||
}
|
||||
// XXX no error handling
|
||||
if conn.GetChannelType(channelId) != "im.ricochet.chat" {
|
||||
conn.OpenChatChannel(channelId)
|
||||
}
|
||||
|
||||
// XXX no message IDs
|
||||
conn.SendMessage(channelId, message.Text)
|
||||
*/
|
||||
}
|
||||
|
||||
// XXX This is inefficient -- it'll usually only be marking the last message
|
||||
// or few messages. Need a better way to know what's unread.
|
||||
func (c *Conversation) MarkReadBeforeMessage(msgId uint64) int {
|
||||
|
@ -227,3 +219,53 @@ func (c *Conversation) MarkReadBeforeMessage(msgId uint64) int {
|
|||
|
||||
return marked
|
||||
}
|
||||
|
||||
// Implement ChatChannelHandler (im.ricochet.chat)
|
||||
func (c *Conversation) ChatMessage(messageID uint32, when time.Time, message string) bool {
|
||||
// XXX sanity checks, message contents, etc
|
||||
log.Printf("chat message: %d %d %v %s", messageID, when, message)
|
||||
|
||||
c.Receive(uint64(messageID), when.Unix(), message)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Conversation) ChatMessageAck(messageID uint32) {
|
||||
// XXX no success field
|
||||
log.Printf("chat ack: %d", messageID)
|
||||
|
||||
c.UpdateSentStatus(uint64(messageID), true)
|
||||
}
|
||||
|
||||
func (c *Conversation) sendMessageToConnection(message *ricochet.Message) (connected bool, err error) {
|
||||
conn := c.Contact.Connection()
|
||||
if conn == nil {
|
||||
err = errors.New("not connected")
|
||||
return
|
||||
}
|
||||
connected = true
|
||||
|
||||
err = conn.Do(func() error {
|
||||
channel := conn.Channel("im.ricochet.chat", channels.Outbound)
|
||||
if channel == nil {
|
||||
if ch, err := conn.RequestOpenChannel("im.ricochet.chat", &channels.ChatChannel{Handler: c}); err != nil {
|
||||
return err
|
||||
} else {
|
||||
channel = ch
|
||||
}
|
||||
}
|
||||
chat, ok := channel.Handler.(*channels.ChatChannel)
|
||||
if !ok {
|
||||
channel.CloseChannel()
|
||||
return errors.New("invalid chat channel")
|
||||
}
|
||||
|
||||
// XXX message id and all of that
|
||||
chat.SendMessage(message.Text)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Printf("chat send failed: %s", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue