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

View File

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

View File

@ -24,7 +24,7 @@ func main() {
echobot.Init(pk, new(application.AcceptAllContactManager))
echobot.OnChatMessage(func(rai *application.RicochetApplicationInstance, id uint32, timestamp time.Time, message string) {
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())
echobot.Run(l)

View File

@ -34,6 +34,14 @@ func (ach *AutoConnectionHandler) OnReady(oc *Connection) {
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 ...
func (ach *AutoConnectionHandler) RegisterChannelHandler(ctype string, handler func() channels.Handler) {
_, exists := ach.handlerMap[ctype]

View File

@ -44,6 +44,7 @@ type Connection struct {
IsInbound bool
Authentication map[string]bool
RemoteHostname string
SupportChannels []string
}
func (rc *Connection) init() {
@ -458,18 +459,33 @@ func (rc *Connection) controlPacket(handler Handler, res *Protocol_Data_Control.
rc.SendRicochetPacket(rc.Conn, 0, raw)
}
} 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)
raw := messageBuilder.FeaturesEnabled([]string{})
rc.traceLog("sending featured enabled empty response")
raw := messageBuilder.FeaturesEnabled(result)
rc.traceLog(fmt.Sprintf("sending featured enabled: %v", result))
rc.SendRicochetPacket(rc.Conn, 0, raw)
} else if res.GetFeaturesEnabled() != nil {
// TODO We should never send out an enabled features
// request.
rc.traceLog("sending unsolicited features enabled response")
rc.SupportChannels = res.GetFeaturesEnabled().GetFeature()
rc.traceLog(fmt.Sprintf("connection supports: %v", rc.SupportChannels))
}
}
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) {
if rc.trace {
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
// will be opened.
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
}
func (och *OutboundConnectionHandler) GetSupportChannels() {
}