package main import ( "encoding/binary" "encoding/json" "fmt" "io" "net" ) type GrainHandler struct { listener net.Listener pool GrainPool } func (h *GrainHandler) GetState(id CartId, reply *Grain) error { grain, err := h.pool.Get(id) if err != nil { return err } *reply = grain return nil } func NewGrainHandler(pool GrainPool, listen string) (*GrainHandler, error) { handler := &GrainHandler{ pool: pool, } l, err := net.Listen("tcp", listen) handler.listener = l return handler, err } func (h *GrainHandler) Serve() { for { // Accept incoming connections conn, err := h.listener.Accept() if err != nil { fmt.Println("Error:", err) continue } // Handle client connection in a goroutine go h.handleClient(conn) } } func (h *GrainHandler) handleClient(conn net.Conn) { fmt.Println("Handling client connection") defer conn.Close() var packet CartPacket for { for { err := binary.Read(conn, binary.LittleEndian, &packet) if err != nil { if err == io.EOF { break } fmt.Println("Error reading packet:", err) } if packet.Version != 2 { fmt.Printf("Unknown version %d", packet.Version) break } switch packet.MessageType { case RemoteHandleMessage: fmt.Printf("Handling message\n") var msg Message err := MessageFromReader(conn, &msg) if err != nil { fmt.Println("Error reading message:", err) } fmt.Printf("Message: %s, %v\n", packet.Id.String(), msg) grain, err := h.pool.Get(packet.Id) if err != nil { fmt.Println("Error getting grain:", err) } _, err = grain.HandleMessage(&msg, false) if err != nil { fmt.Println("Error handling message:", err) } SendPacket(conn, ResponseBody, func(w io.Writer) error { data, err := json.Marshal(grain) if err != nil { return err } w.Write(data) return nil }) case RemoteGetState: fmt.Printf("Package: %s %v\n", packet.Id.String(), packet) grain, err := h.pool.Get(packet.Id) if err != nil { fmt.Println("Error getting grain:", err) } SendPacket(conn, ResponseBody, func(w io.Writer) error { data, err := json.Marshal(grain) if err != nil { return err } w.Write(data) return nil }) } } } }