mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-06-10 04:12:07 +03:00
Set.Each, also builtin Channel broadcast goroutine
This commit is contained in:
parent
7beb7f99bb
commit
a1d5cc6735
@ -3,6 +3,7 @@ package chat
|
|||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const historyLen = 20
|
const historyLen = 20
|
||||||
|
const channelBuffer = 10
|
||||||
|
|
||||||
// Channel definition, also a Set of User Items
|
// Channel definition, also a Set of User Items
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
@ -10,19 +11,35 @@ type Channel struct {
|
|||||||
topic string
|
topic string
|
||||||
history *History
|
history *History
|
||||||
users *Set
|
users *Set
|
||||||
broadcast chan<- Message
|
broadcast chan Message
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChannel(id string, broadcast chan<- Message) *Channel {
|
// Create new channel and start broadcasting goroutine.
|
||||||
|
func NewChannel(id string) *Channel {
|
||||||
|
broadcast := make(chan Message, channelBuffer)
|
||||||
|
|
||||||
ch := Channel{
|
ch := Channel{
|
||||||
id: id,
|
id: id,
|
||||||
broadcast: broadcast,
|
broadcast: broadcast,
|
||||||
history: NewHistory(historyLen),
|
history: NewHistory(historyLen),
|
||||||
users: NewSet(),
|
users: NewSet(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for m := range broadcast {
|
||||||
|
ch.users.Each(func(u Item) {
|
||||||
|
u.(*User).Send(m)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return &ch
|
return &ch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ch *Channel) Close() {
|
||||||
|
close(ch.broadcast)
|
||||||
|
}
|
||||||
|
|
||||||
func (ch *Channel) Send(m Message) {
|
func (ch *Channel) Send(m Message) {
|
||||||
ch.broadcast <- m
|
ch.broadcast <- m
|
||||||
}
|
}
|
||||||
|
@ -8,20 +8,12 @@ import (
|
|||||||
func TestChannel(t *testing.T) {
|
func TestChannel(t *testing.T) {
|
||||||
var expected, actual []byte
|
var expected, actual []byte
|
||||||
|
|
||||||
out := make(chan Message)
|
|
||||||
defer close(out)
|
|
||||||
|
|
||||||
s := &MockScreen{}
|
s := &MockScreen{}
|
||||||
u := NewUser("foo")
|
u := NewUser("foo")
|
||||||
|
|
||||||
go func() {
|
ch := NewChannel("")
|
||||||
for msg := range out {
|
defer ch.Close()
|
||||||
t.Logf("Broadcasted: ", msg.String())
|
|
||||||
u.Send(msg)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
ch := NewChannel("", out)
|
|
||||||
err := ch.Join(u)
|
err := ch.Join(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
15
chat/host.go
15
chat/host.go
@ -24,18 +24,5 @@ func (h *Host) broadcast(ch *Channel, m Message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Host) CreateChannel(id string) *Channel {
|
func (h *Host) CreateChannel(id string) *Channel {
|
||||||
out := make(chan Message, 20)
|
return NewChannel(id)
|
||||||
ch := NewChannel(id, out)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for msg := range out {
|
|
||||||
if msg.IsCommand() {
|
|
||||||
go h.handleCommand(msg)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
h.broadcast(ch, msg)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ch
|
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,15 @@ func (s *Set) Remove(item Item) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loop over every item while holding a read lock and apply fn
|
||||||
|
func (s *Set) Each(fn func(item Item)) {
|
||||||
|
s.RLock()
|
||||||
|
for _, item := range s.lookup {
|
||||||
|
fn(item)
|
||||||
|
}
|
||||||
|
s.RUnlock()
|
||||||
|
}
|
||||||
|
|
||||||
// List users by prefix, case insensitive
|
// List users by prefix, case insensitive
|
||||||
func (s *Set) ListPrefix(prefix string) []Item {
|
func (s *Set) ListPrefix(prefix string) []Item {
|
||||||
r := []Item{}
|
r := []Item{}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user