musique/server/router/router.go
2022-12-16 16:34:52 +01:00

68 lines
1.3 KiB
Go

package router
import (
"encoding/json"
"musique/server/proto"
"net"
"log"
"fmt"
)
type Route func(incoming net.Conn, request proto.Request) interface{}
type Router struct {
routes map[string]Route
port uint16
baseIP string
}
func (router *Router) Add(name string, route Route) {
if router.routes == nil {
router.routes = make(map[string]Route)
}
router.routes[name] = route
}
func (router *Router) Run(ip string, port uint16) (<-chan struct{}, error) {
router.port = port
router.baseIP = ip
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", router.baseIP, router.port))
if err != nil {
return nil, err
}
exit := make(chan struct{})
go func() {
defer listener.Close()
defer close(exit)
for {
incoming, err := listener.Accept()
if err != nil {
log.Println("failed to accept connection:", err)
}
go router.handleIncoming(incoming)
}
}()
return exit, nil
}
func (router *Router) handleIncoming(incoming net.Conn) {
defer incoming.Close()
request := proto.Request{}
json.NewDecoder(incoming).Decode(&request)
log.Printf("%s: %+v\n", incoming.RemoteAddr(), request)
if handler, ok := router.routes[request.Type]; ok {
if response := handler(incoming, request); response != nil {
json.NewEncoder(incoming).Encode(response)
}
} else {
log.Printf("unrecongized route: %v\n", request.Type)
}
}