forked from openprivacy/libricochet-go
Adding Simple Application Broadcast & Features Enabled
This commit is contained in:
parent
1433b31e6f
commit
f537fb4f76
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,3 +88,7 @@ func (och *OutboundConnectionHandler) ProcessAuthAsClient(identity identity.Iden
|
||||||
}
|
}
|
||||||
return false, utils.ServerRejectedClientConnectionError
|
return false, utils.ServerRejectedClientConnectionError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (och *OutboundConnectionHandler) GetSupportChannels() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue