package main import ( "fmt" "log" "net" "time" pb "gordenko.dev/dima/protolab/gen/service/v1" "gordenko.dev/dima/protolab/bin" ) const ( Port = 8080 ) func handleConnection(conn net.Conn) { defer conn.Close() log.Printf("client %s connected\n", conn.RemoteAddr().String()) for { var ( reqWrapper pb.RequestWrapper respWrapper *pb.ResponseWrapper ) err := bin.ReadMessage(conn, &reqWrapper) if err != nil { log.Fatalf("read request: %v\n", err) } switch p := reqWrapper.Payload.(type) { case *pb.RequestWrapper_SendTelemetry: data := p.SendTelemetry log.Printf("telemetry received from %s: Temp %.2f°C, BatteryLevel %v%%\n", data.GetDeviceId(), data.GetTemperature(), data.GetBatteryLevel()) respWrapper = &pb.ResponseWrapper{ Payload: &pb.ResponseWrapper_TelemetryResp{ TelemetryResp: &pb.TelemetryResponse{ ResultCode: pb.TelemetryResponse_RESULT_CODE_SUCCEEDED, }, }, } case *pb.RequestWrapper_Ping: data := p.Ping log.Printf("ping received, client time %s\n", time.Unix(data.GetTimestamp(), 0).Format(time.RFC3339)) respWrapper = &pb.ResponseWrapper{ Payload: &pb.ResponseWrapper_PingResp{ PingResp: &pb.PingResponse{ ServerTimestamp: time.Now().Unix(), }, }, } default: log.Printf("unknown request received: %T\n", p) } err = bin.WriteMessage(conn, respWrapper) if err != nil { log.Fatalf("send response: %v\n", err) } else { log.Println("response sent") } } } func main() { listener, err := net.Listen("tcp", fmt.Sprintf(":%d", Port)) if err != nil { log.Fatalf("net.Listen: %v\n", err) } defer listener.Close() log.Printf("server started on port %d", Port) for { conn, err := listener.Accept() if err != nil { log.Printf("listener.Accept: %v", err) continue } go handleConnection(conn) } }