can send messages back to specific and ALL viewers

master v0.1.3
bel 2023-03-25 11:27:49 -06:00
parent 3f35f7f936
commit 3264d9ad55
5 changed files with 122 additions and 2 deletions

View File

@ -4,3 +4,4 @@ export BUTTON_V01=true
export WRAP_REFRESH_ON_SIGUSR1=true
export MAIN_INTERVAL_DURATION=5ms
export OUTPUT_KEYBOARD=false
export BUTTON_V01_CONFIG=./config.d/mayhem-party.d/v01.yaml

View File

@ -1 +1 @@
players_offset_1.yaml
players_offset_4.yaml

View File

@ -0,0 +1,21 @@
feedback:
addr: :17071
users:
bel:
player: 2
message: its bel
broadcast:
message: 8
players:
- {}
- transformation:
w: t
a: f
s: g
d: h
q: r
e: y
1: 5
2: 6
3: 7
4: 8

View File

@ -6,6 +6,7 @@ import (
"io/ioutil"
"log"
"mayhem-party/src/device/input/raw"
"net/http"
"os"
"time"
@ -31,6 +32,9 @@ type (
N string
}
v01Cfg struct {
Feedback struct {
Addr string
}
Users map[string]struct {
Player int
Message string
@ -47,12 +51,41 @@ func NewV01(ctx context.Context, src raw.Raw) V01 {
b, _ := ioutil.ReadFile(FlagButtonV01Config)
yaml.Unmarshal(b, &cfg)
ctx, can := context.WithCancel(ctx)
return V01{
result := V01{
ctx: ctx,
can: can,
src: src,
cfg: cfg,
}
go result.listen()
return result
}
func (v01 V01) listen() {
if v01.cfg.Feedback.Addr == "" {
return
}
s := &http.Server{
Addr: v01.cfg.Feedback.Addr,
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r = r.WithContext(v01.ctx)
user, ok := v01.cfg.Users[r.URL.Query().Get("user")]
if !ok {
user = v01.cfg.Users["broadcast"]
}
w.Write([]byte(user.Message))
}),
}
go func() {
<-v01.ctx.Done()
log.Println("closing v01 server")
s.Close()
}()
log.Println("starting v01 server")
if err := s.ListenAndServe(); err != nil && v01.ctx.Err() == nil {
log.Println("err with v01 server", err)
panic(err)
}
}
func (v01 V01) CloseWrap() raw.Raw {

View File

@ -3,7 +3,9 @@ package button_test
import (
"context"
"fmt"
"io"
"mayhem-party/src/device/input/button"
"net/http"
"os"
"path"
"testing"
@ -14,6 +16,7 @@ func TestV01(t *testing.T) {
src := constSrc(fmt.Sprintf(`{"T":%v,"U":"bel","Y":"abc","N":"cde"}`, time.Now().UnixNano()/int64(time.Millisecond)-50))
t.Logf("(%v) %s", len(src), src.Read())
v01 := button.NewV01(context.Background(), src)
defer v01.Close()
got := v01.Read()
want := []button.Button{
{Down: true, Char: 'a'},
@ -50,6 +53,7 @@ func TestV01WithCfg(t *testing.T) {
t.Run("unknown user ignored", func(t *testing.T) {
v01 := button.NewV01(context.Background(), constSrc(`{"U":"qt","Y":"w"}`))
defer v01.Close()
got := v01.Read()
if len(got) != 0 {
t.Error(got)
@ -58,6 +62,7 @@ func TestV01WithCfg(t *testing.T) {
t.Run("player2", func(t *testing.T) {
v01 := button.NewV01(context.Background(), constSrc(`{"U":"bel","Y":"w","N":"w"}`))
defer v01.Close()
got := v01.Read()
if len(got) != 2 {
t.Error(got)
@ -70,3 +75,63 @@ func TestV01WithCfg(t *testing.T) {
}
})
}
func TestV01Feedback(t *testing.T) {
d := t.TempDir()
p := path.Join(d, "cfg.yaml")
os.WriteFile(p, []byte(`
feedback:
addr: :27071
users:
bel:
player: 2
message: to bel
broadcast:
message: to everyone
players:
- transformation:
w: t
- transformation:
w: i
`), os.ModePerm)
button.FlagButtonV01Config = p
ctx, can := context.WithCancel(context.Background())
defer can()
v01 := button.NewV01(ctx, constSrc(`{"U":"qt","Y":"w"}`))
defer v01.Close()
for {
time.Sleep(time.Millisecond * 100)
resp, err := http.Get("http://localhost:27071?user=bel")
if err != nil {
continue
}
resp.Body.Close()
break
}
t.Run("specific user", func(t *testing.T) {
resp, err := http.Get("http://localhost:27071?user=bel")
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
if string(b) != "to bel" {
t.Error(b)
}
})
t.Run("broadcast", func(t *testing.T) {
resp, err := http.Get("http://localhost:27071")
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
if string(b) != "to everyone" {
t.Error(b)
}
})
}