|
|
|
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
|
|
|
|
}
|