Adding Simple Application Broadcast & Features Enabled

This commit is contained in:
Sarah Jamie Lewis 2018-01-01 10:06:58 -08:00
parent 1433b31e6f
commit f537fb4f76
7 changed files with 71 additions and 11 deletions

View File

@ -9,6 +9,7 @@ import (
"log" "log"
"net" "net"
"time" "time"
"sync"
) )
// RicochetApplication bundles many useful constructs that are // RicochetApplication bundles many useful constructs that are
@ -18,7 +19,11 @@ type RicochetApplication struct {
privateKey *rsa.PrivateKey privateKey *rsa.PrivateKey
chatMessageHandler func(*RicochetApplicationInstance, uint32, time.Time, string) chatMessageHandler func(*RicochetApplicationInstance, uint32, time.Time, string)
chatMessageAckHandler func(*RicochetApplicationInstance, uint32) chatMessageAckHandler func(*RicochetApplicationInstance, uint32)
onConnected func(*RicochetApplicationInstance)
onLeave func(*RicochetApplicationInstance)
l net.Listener l net.Listener
instances []*RicochetApplicationInstance
lock sync.Mutex
} }
type RicochetApplicationInstance struct { type RicochetApplicationInstance struct {
@ -27,6 +32,7 @@ type RicochetApplicationInstance struct {
RemoteHostname string RemoteHostname string
ChatMessageHandler func(*RicochetApplicationInstance, uint32, time.Time, string) ChatMessageHandler func(*RicochetApplicationInstance, uint32, time.Time, string)
ChatMessageAckHandler func(*RicochetApplicationInstance, uint32) ChatMessageAckHandler func(*RicochetApplicationInstance, uint32)
OnLeave func(*RicochetApplicationInstance)
} }
func (rai *RicochetApplicationInstance) ContactRequest(name string, message string) string { func (rai *RicochetApplicationInstance) ContactRequest(name string, message string) string {
@ -83,6 +89,14 @@ func (ra *RicochetApplication) OnChatMessageAck(call func(*RicochetApplicationIn
ra.chatMessageAckHandler = call ra.chatMessageAckHandler = call
} }
func (ra *RicochetApplication) OnConnected(call func(*RicochetApplicationInstance)) {
ra.onConnected = call
}
func (ra *RicochetApplication) OnLeave(call func(*RicochetApplicationInstance)) {
ra.onLeave = call
}
func (ra *RicochetApplication) handleConnection(conn net.Conn) { func (ra *RicochetApplication) handleConnection(conn net.Conn) {
rc, err := goricochet.NegotiateVersionInbound(conn) rc, err := goricochet.NegotiateVersionInbound(conn)
if err != nil { if err != nil {
@ -99,13 +113,14 @@ func (ra *RicochetApplication) handleConnection(conn net.Conn) {
conn.Close() conn.Close()
return return
} }
rc.TraceLog(true)
rai := new(RicochetApplicationInstance) rai := new(RicochetApplicationInstance)
rai.Init() rai.Init()
rai.RemoteHostname = rc.RemoteHostname rai.RemoteHostname = rc.RemoteHostname
rai.connection = rc rai.connection = rc
rai.ChatMessageHandler = ra.chatMessageHandler rai.ChatMessageHandler = ra.chatMessageHandler
rai.ChatMessageAckHandler = ra.chatMessageAckHandler rai.ChatMessageAckHandler = ra.chatMessageAckHandler
rai.OnLeave = ra.onLeave
rai.RegisterChannelHandler("im.ricochet.contact.request", func() channels.Handler { rai.RegisterChannelHandler("im.ricochet.contact.request", func() channels.Handler {
contact := new(channels.ContactRequestChannel) contact := new(channels.ContactRequestChannel)
@ -117,9 +132,25 @@ func (ra *RicochetApplication) handleConnection(conn net.Conn) {
chat.Handler = rai chat.Handler = rai
return chat return chat
}) })
ra.lock.Lock()
ra.instances = append(ra.instances, rai)
ra.lock.Unlock()
go ra.onConnected(rai)
rc.Process(rai) rc.Process(rai)
} }
func (rai *RicochetApplicationInstance) OnClosed(err error) {
rai.OnLeave(rai)
}
func (ra *RicochetApplication) Broadcast(message string) {
ra.lock.Lock()
for _,rai := range ra.instances {
rai.SendChatMessage(message)
}
ra.lock.Unlock()
}
func (ra *RicochetApplication) Shutdown() { func (ra *RicochetApplication) Shutdown() {
log.Printf("Closing") log.Printf("Closing")
ra.l.Close() ra.l.Close()

View File

@ -23,9 +23,8 @@ func main() {
commandbot.Init(pk, new(application.AcceptAllContactManager)) commandbot.Init(pk, new(application.AcceptAllContactManager))
commandbot.OnChatMessage(func(rai *application.RicochetApplicationInstance, id uint32, timestamp time.Time, message string) { commandbot.OnChatMessage(func(rai *application.RicochetApplicationInstance, id uint32, timestamp time.Time, message string) {
if message == "/" { log.Printf("message from %v - %v", rai.RemoteHostname, message)
rai.SendChatMessage(message) go echobot.Broadcast(rai.RemoteHostname + " " + message)
}
}) })
log.Printf("commandbot listening on %s", l.Addr().String()) log.Printf("commandbot listening on %s", l.Addr().String())
commandbot.Run(l) commandbot.Run(l)

View File

@ -24,7 +24,7 @@ func main() {
echobot.Init(pk, new(application.AcceptAllContactManager)) echobot.Init(pk, new(application.AcceptAllContactManager))
echobot.OnChatMessage(func(rai *application.RicochetApplicationInstance, id uint32, timestamp time.Time, message string) { echobot.OnChatMessage(func(rai *application.RicochetApplicationInstance, id uint32, timestamp time.Time, message string) {
log.Printf("message from %v - %v", rai.RemoteHostname, message) log.Printf("message from %v - %v", rai.RemoteHostname, message)
rai.SendChatMessage(message) go echobot.Broadcast(rai.RemoteHostname + " " + message)
}) })
log.Printf("echobot listening on %s", l.Addr().String()) log.Printf("echobot listening on %s", l.Addr().String())
echobot.Run(l) echobot.Run(l)

View File

@ -34,6 +34,14 @@ func (ach *AutoConnectionHandler) OnReady(oc *Connection) {
func (ach *AutoConnectionHandler) OnClosed(err error) { func (ach *AutoConnectionHandler) OnClosed(err error) {
} }
func (ach *AutoConnectionHandler) GetSupportedChannelTypes() []string {
supported := []string{}
for k,_ := range ach.handlerMap {
supported = append(supported, k)
}
return supported
}
// RegisterChannelHandler ... // RegisterChannelHandler ...
func (ach *AutoConnectionHandler) RegisterChannelHandler(ctype string, handler func() channels.Handler) { func (ach *AutoConnectionHandler) RegisterChannelHandler(ctype string, handler func() channels.Handler) {
_, exists := ach.handlerMap[ctype] _, exists := ach.handlerMap[ctype]

View File

@ -44,6 +44,7 @@ type Connection struct {
IsInbound bool IsInbound bool
Authentication map[string]bool Authentication map[string]bool
RemoteHostname string RemoteHostname string
SupportChannels []string
} }
func (rc *Connection) init() { func (rc *Connection) init() {
@ -458,18 +459,33 @@ func (rc *Connection) controlPacket(handler Handler, res *Protocol_Data_Control.
rc.SendRicochetPacket(rc.Conn, 0, raw) rc.SendRicochetPacket(rc.Conn, 0, raw)
} }
} else if res.GetEnableFeatures() != nil { } else if res.GetEnableFeatures() != nil {
rc.traceLog("received features enabled packet") rc.traceLog("received enable features packet")
featuresToEnable := res.GetEnableFeatures().GetFeature()
supportChannels := handler.GetSupportedChannelTypes()
result := []string{}
for _,v := range featuresToEnable {
for _,s := range supportChannels {
if v == s {
result = append(result, v)
}
}
}
messageBuilder := new(utils.MessageBuilder) messageBuilder := new(utils.MessageBuilder)
raw := messageBuilder.FeaturesEnabled([]string{}) raw := messageBuilder.FeaturesEnabled(result)
rc.traceLog("sending featured enabled empty response") rc.traceLog(fmt.Sprintf("sending featured enabled: %v", result))
rc.SendRicochetPacket(rc.Conn, 0, raw) rc.SendRicochetPacket(rc.Conn, 0, raw)
} else if res.GetFeaturesEnabled() != nil { } else if res.GetFeaturesEnabled() != nil {
// TODO We should never send out an enabled features rc.SupportChannels = res.GetFeaturesEnabled().GetFeature()
// request. rc.traceLog(fmt.Sprintf("connection supports: %v", rc.SupportChannels))
rc.traceLog("sending unsolicited features enabled response")
} }
} }
func (rc *Connection) EnableFeatures(features []string) {
messageBuilder := new(utils.MessageBuilder)
raw := messageBuilder.EnableFeatures(features)
rc.SendRicochetPacket(rc.Conn, 0, raw)
}
func (rc *Connection) traceLog(message string) { func (rc *Connection) traceLog(message string) {
if rc.trace { if rc.trace {
log.Printf(message) log.Printf(message)

View File

@ -25,4 +25,6 @@ type Handler interface {
// A non-nil return from this function does not guarantee that the channel // A non-nil return from this function does not guarantee that the channel
// will be opened. // will be opened.
OnOpenChannelRequest(ctype string) (channels.Handler, error) OnOpenChannelRequest(ctype string) (channels.Handler, error)
GetSupportedChannelTypes() []string
} }

View File

@ -88,3 +88,7 @@ func (och *OutboundConnectionHandler) ProcessAuthAsClient(identity identity.Iden
} }
return false, utils.ServerRejectedClientConnectionError return false, utils.ServerRejectedClientConnectionError
} }
func (och *OutboundConnectionHandler) GetSupportChannels() {
}