package grpc import ( "context" pb "spektr/internal/grpc/pb" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) type Client struct { conn *grpc.ClientConn cancel context.CancelFunc stream pb.ReceiverService_ConnectClient } func Dial(ctx context.Context, addr string) (*Client, error) { conn, err := grpc.DialContext(ctx, addr, grpc.WithBlock(), grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, err } client := pb.NewReceiverServiceClient(conn) streamCtx, cancel := context.WithCancel(context.Background()) stream, err := client.Connect(streamCtx) if err != nil { cancel() _ = conn.Close() return nil, err } return &Client{conn: conn, cancel: cancel, stream: stream}, nil } func (c *Client) Send(msg *pb.ClientMessage) (*pb.ServerMessage, error) { if err := c.stream.Send(msg); err != nil { return nil, err } return c.stream.Recv() } func (c *Client) Close() error { if c.cancel != nil { c.cancel() } return c.conn.Close() }