do a few
This commit is contained in:
parent
a6ef3bf1b6
commit
f174c4e02d
14 changed files with 626 additions and 1 deletions
106
x/meanstoanend/server.go
Normal file
106
x/meanstoanend/server.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
package meanstoanend
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/charmbracelet/log"
|
||||
)
|
||||
|
||||
type message struct {
|
||||
a int32
|
||||
b int32
|
||||
}
|
||||
|
||||
type client struct {
|
||||
conn net.Conn
|
||||
prices map[int32]int32
|
||||
log *log.Logger
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func (c *client) handleMessage() error {
|
||||
_, err := io.ReadFull(c.conn, c.buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := new(message)
|
||||
|
||||
_, err = binary.Decode(c.buf[1:5], binary.BigEndian, &msg.a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = binary.Decode(c.buf[5:], binary.BigEndian, &msg.b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch c.buf[0] {
|
||||
case 'I':
|
||||
c.prices[msg.a] = msg.b
|
||||
case 'Q':
|
||||
var i int64
|
||||
var mean int64
|
||||
|
||||
for k, v := range c.prices {
|
||||
if k >= msg.a && k <= msg.b {
|
||||
mean += int64(v)
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
mean /= i
|
||||
}
|
||||
|
||||
binary.Write(c.conn, binary.BigEndian, int32(mean))
|
||||
default:
|
||||
c.conn.Close()
|
||||
return errors.New("bad message")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func acceptConn(conn net.Conn) {
|
||||
log.Info("accepting connection", "remote", conn.RemoteAddr())
|
||||
|
||||
var err error
|
||||
|
||||
c := new(client)
|
||||
c.log = log.Default().WithPrefix(conn.RemoteAddr().String())
|
||||
|
||||
c.buf = make([]byte, 9)
|
||||
c.conn = conn
|
||||
c.prices = map[int32]int32{}
|
||||
|
||||
defer c.conn.Close()
|
||||
|
||||
for {
|
||||
c.log.Debug("waiting for message", "remote", conn.RemoteAddr())
|
||||
err = c.handleMessage()
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
c.log.Error("unable to read data", "err", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
c.log.Info("released connection")
|
||||
}
|
||||
|
||||
func New(listener net.Listener) error {
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go acceptConn(conn)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue