Я написал службу GRPC .NET Core Worker, которая действует как сервер, и консольное приложение .NET Core, которое действует как клиент GRPC. Оба следуют инструкциям, в которых используются файлы helloworld.proto, но я расширил их, чтобы сервер мог находиться на одном компьютере, а клиент - на другом.
Сервер выглядит следующим образом:
class GreeterImpl : Greeter.GreeterBase
{
// Server side handler of the SayHello RPC
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
}
}
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private const int PORT = 5221;
private Server m_Server;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Starting grpc...");
_logger.LogInformation("Local machine name: {computer}, Port: {port}", Environment.MachineName, PORT);
m_Server = new Server
{
Services = { Greeter.BindService(new GreeterImpl()) },
Ports = { new ServerPort(Environment.MachineName, PORT, ServerCredentials.Insecure) }
};
m_Server.Start();
return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Shutting down...");
m_Server.ShutdownAsync().Wait();
return base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
//_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
Клиент выглядит следующим образом:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter the server IP address or name:");
string server = Console.ReadLine();
Console.WriteLine($"The server entered was: {server}");
Channel channel = new Channel(string.Format("{0}:5221", server), ChannelCredentials.Insecure);
var client = new Greeter.GreeterClient(channel);
string user = "you";
var reply = client.SayHello(new HelloRequest { Name = user });
Console.WriteLine("Greeting: " + reply.Message);
channel.ShutdownAsync().Wait();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
В этом случае он использует порт 5221 для подключения.
Я успешно запустил программу:
- Сервер на компьютере Windows, клиент на другом компьютере Windows.
- Сервер на компьютере Windows,клиент на компьютере Linux с opensuse.
- сервер и клиент на одном компьютере Linux с Linux с открытым доступом.
Конфигурация, которую я не могу получить, - это когда сервер работает наКомпьютер Linux с opensuse и клиент на компьютере с Windows. Я получаю ошибку: необработанное исключение. Grpc.Core.RpcException: Status (StatusCode = недоступно, Detail = "не удалось подключиться ко всем адресам"). Это происходит на компьютере под управлением Windows, на котором работает клиент. Сервер, работающий на opensuse linux, не подвержен уязвимости.
Linux и компьютер Windows могут пропинговать друг друга по имени и IP-адресу. Порт 5221 открыт на компьютере Linux. Я не гуру Linux, и я думаю, что это проблема с сетью на этом компьютере во время работы сервера. У кого-нибудь есть идеи?