ssh-chat/chat/channel.go

86 lines
1.4 KiB
Go
Raw Normal View History

2014-12-21 01:45:10 +01:00
package chat
import "fmt"
2014-12-21 01:45:10 +01:00
const historyLen = 20
const channelBuffer = 10
2014-12-21 01:45:10 +01:00
// Channel definition, also a Set of User Items
type Channel struct {
topic string
history *History
users *Set
broadcast chan Message
2014-12-21 01:45:10 +01:00
}
// Create new channel and start broadcasting goroutine.
2014-12-23 07:21:07 +01:00
func NewChannel() *Channel {
broadcast := make(chan Message, channelBuffer)
2014-12-21 01:45:10 +01:00
ch := Channel{
broadcast: broadcast,
history: NewHistory(historyLen),
users: NewSet(),
2014-12-21 01:45:10 +01:00
}
go func() {
for m := range broadcast {
2014-12-23 07:21:07 +01:00
// TODO: Handle commands etc?
ch.users.Each(func(u Item) {
2014-12-23 07:21:07 +01:00
user := u.(*User)
if m.from == user {
// Skip
return
}
err := user.Send(m)
if err != nil {
ch.Leave(user)
user.Close()
}
})
}
}()
2014-12-21 01:45:10 +01:00
return &ch
}
func (ch *Channel) Close() {
ch.users.Each(func(u Item) {
u.(*User).Close()
})
ch.users.Clear()
close(ch.broadcast)
}
2014-12-21 01:45:10 +01:00
func (ch *Channel) Send(m Message) {
ch.broadcast <- m
2014-12-21 01:45:10 +01:00
}
func (ch *Channel) Join(u *User) error {
err := ch.users.Add(u)
if err != nil {
return err
}
s := fmt.Sprintf("%s joined. (Connected: %d)", u.Name(), ch.users.Len())
ch.Send(*NewMessage(s))
return nil
2014-12-21 01:45:10 +01:00
}
func (ch *Channel) Leave(u *User) error {
err := ch.users.Remove(u)
if err != nil {
return err
}
s := fmt.Sprintf("%s left.", u.Name())
ch.Send(*NewMessage(s))
return nil
2014-12-21 01:45:10 +01:00
}
func (ch *Channel) Topic() string {
return ch.topic
}
func (ch *Channel) SetTopic(s string) {
ch.topic = s
}