package server import ( "fmt" "sync" "net" "context" "google.golang.org/grpc" pb "FRMS/internal/pkg/grpc" ) // the goal here is to set up a gRPC handler to respond to reactor pings with their IP and to establish a new coordinator for that specific reactor type ReactorListener struct { // exporting for easy use in the short term Reactor map[uint32]*ReactorCoordinator Ip string Port int Err chan error mu sync.Mutex pb.UnimplementedHandshakeServer } func NewReactorListener(ch chan error) *ReactorListener { m := make(map[uint32]*ReactorCoordinator) ip := "192.1.168.136" port := 2000 return &ReactorListener{Err:ch, Reactor:m, Port:port, Ip:ip} } func (r *ReactorListener) GetIp() string { r.mu.Lock() defer r.mu.Unlock() return r.Ip } func (r *ReactorListener) GetPort() int { r.mu.Lock() defer r.mu.Unlock() return r.Port } func (r *ReactorListener) Start() { // start grpc server and implement reciever err := r.Register() if err != nil { r.Err <- err } // reactor listener started and grpc library will execute listener fmt.Printf("Started listener on %v:%v\n",r.Ip,r.Port) } func (r *ReactorListener) Register() error { // creates a gRPC service and binds it to our handler lis, err := net.Listen("tcp", fmt.Sprintf("%v:%v",r.Ip,r.Port)) if err != nil { return err } grpcServer := grpc.NewServer() pb.RegisterHandshakeServer(grpcServer, r) go grpcServer.Serve(lis) return nil } func (r *ReactorListener) ReactorDiscoveryHandler(ctx context.Context, ping *pb.ReactorDiscoveryRequest) (*pb.ReactorDiscoveryResponse, error) { // incoming reactor ping need to spawn coord r.mu.Lock() rc, ok := r.Reactor[ping.GetId()] fmt.Printf("Reactor %v has connected from addr %v and provided port %v\n",ping.GetId(),ping.GetIp(),ping.GetPort()) // if reactor exists if ok { go rc.Start() } else { rc := NewReactorCoordinator(r,ping.GetIp(),ping.GetModel(),int(ping.GetPort()),ping.GetId()) go rc.Start() r.Reactor[ping.GetId()] = rc } return &pb.ReactorDiscoveryResponse{Success:true}, nil }