99 lines
2.4 KiB
Go

package grpcserver
import (
"context"
"fmt"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/server"
"github.com/kaspanet/kaspad/util/panics"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/peer"
"net"
)
type gRPCServer struct {
onConnectedHandler server.OnConnectedHandler
listeningAddresses []string
server *grpc.Server
}
// MaxMessageSize is the max size allowed for a message
const MaxMessageSize = 1024 * 1024 * 10 // 10MB
// newGRPCServer creates a gRPC server
func newGRPCServer(listeningAddresses []string) *gRPCServer {
return &gRPCServer{
server: grpc.NewServer(grpc.MaxRecvMsgSize(MaxMessageSize), grpc.MaxSendMsgSize(MaxMessageSize)),
listeningAddresses: listeningAddresses,
}
}
func (s *gRPCServer) Start() error {
if s.onConnectedHandler == nil {
return errors.New("onConnectedHandler is nil")
}
for _, listenAddress := range s.listeningAddresses {
err := s.listenOn(listenAddress)
if err != nil {
return err
}
}
log.Debugf("Server started with MaxMessageSize %d", MaxMessageSize)
return nil
}
func (s *gRPCServer) listenOn(listenAddr string) error {
listener, err := net.Listen("tcp", listenAddr)
if err != nil {
return errors.Wrapf(err, "error listening on %s", listenAddr)
}
spawn("gRPCServer.listenOn-Serve", func() {
err := s.server.Serve(listener)
if err != nil {
panics.Exit(log, fmt.Sprintf("error serving on %s: %+v", listenAddr, err))
}
})
log.Infof("Server listening on %s", listenAddr)
return nil
}
func (s *gRPCServer) Stop() error {
s.server.GracefulStop()
return nil
}
// SetOnConnectedHandler sets the peer connected handler
// function for the server
func (s *gRPCServer) SetOnConnectedHandler(onConnectedHandler server.OnConnectedHandler) {
s.onConnectedHandler = onConnectedHandler
}
func (s *gRPCServer) handleInboundConnection(ctx context.Context, stream grpcStream) error {
peerInfo, ok := peer.FromContext(ctx)
if !ok {
return errors.Errorf("Error getting stream peer info from context")
}
tcpAddress, ok := peerInfo.Addr.(*net.TCPAddr)
if !ok {
return errors.Errorf("non-tcp connections are not supported")
}
connection := newConnection(s, tcpAddress, stream, nil)
err := s.onConnectedHandler(connection)
if err != nil {
return err
}
log.Infof("Incoming connection from %s", peerInfo.Addr)
<-connection.stopChan
return nil
}