我是gRPC的新手,正在尝试使用cactuaroid中的聊天服务器/客户端示例来学习它。我修改了代码,以显示WPF应用程序中长时间运行的任务的进度。所有代码都在.NET5上运行,我使用的是最新版本的gRPC软件包。
使用计算机的IP地址时,该过程工作正常,但是当为gRPC客户端使用计算机名称时,我收到“DNS解析失败”异常(计算机名称为“skylake”):
RpcException: Status(StatusCode=“Unavailable”, Detail=“DNS 解析 failed for service: skylake:6001”, DebugException=“Grpc.Core.Internal.CoreErrorDetailException: {”created“:”@1615312867.300000000“,”description“:”Resolver transient failure“,”file“:”......\src\core\ext\filters\client_channel\client_channel.cc“,”file_line“:2138,”referenced_errors“:[{”created“:”@1615312867.300000000“,”description“:”DNS 解析失败服务: skylake:6001“,”file“:”......\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.cc“,”file_line“:362,”grpc_status“:14,”referenced_errors“:[{”created“:”@1615312867.300000000“,”description“:”C-ares status is not ARES_SUCCESS qtype=AAAA name=skylake is_balancer=0: 無法聯繫 DNS 伺服器“,”file“:”......\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc“,“file_line”:716,“referenced_errors”:[{“created”:“@1615312866.142000000”,“description”:“C-ares status is not ARES_SUCCESS qtype=A name=skylake is_balancer=0: Can not contact DNS servers”,“file”:“......\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc”,“file_line”:716}]}]}]}]}“)
我用telnet skylake 6001验证了我可以到达端口。我在本地测试,客户端和服务器都在同一台机器上。奇怪的是,gRPC服务器似乎对计算机名没有问题。只是客户对它有意见。
服务器代码:
[Export(typeof(IService))]
public class ProgressServiceGrpcServer : Progress.ProgressBase, IService
{
[Import]
private Logger m_logger = null;
[Import]
private ProgressService m_progressService = null;
private readonly Empty m_empty = new Empty();
private const int Port = 6001;
private readonly Grpc.Core.Server m_server;
public ProgressServiceGrpcServer()
{
m_server = new Grpc.Core.Server
{
Services =
{
Progress.BindService(this)
.Intercept(new IpAddressAuthenticator())
},
Ports =
{
new ServerPort("skylake", Port, ServerCredentials.Insecure)
}
};
}
public void Start()
{
m_server.Start();
m_logger.Info("Started.");
}
public override async Task Subscribe(ChannelName channelName, IServerStreamWriter<ProgressReport> responseStream, ServerCallContext context)
{
context.CancellationToken.Register(() => m_logger.Info($"{context.Host} cancels subscription."));
try
{
await m_progressService.GetProgressReportsAsObservable(channelName)
.ToAsyncEnumerable()
.ForEachAwaitAsync(async (x) => await responseStream.WriteAsync(x), context.CancellationToken)
.ConfigureAwait(false);
}
catch (TaskCanceledException)
{
m_logger.Info($"{context.Host} unsubscribed.");
}
}
public override Task<Empty> Write(ProgressReport request, ServerCallContext context)
{
m_logger.Info($"{context.Host} {request}");
m_progressService.Add(request);
return Task.FromResult(m_empty);
}
}
客户端代码:
public class ProgressServiceClient
{
private readonly Progress.ProgressClient m_client =
new Progress.ProgressClient(
new Channel("skylake”, 6001, ChannelCredentials.Insecure));
public async Task Write(ProgressReport progressReport)
{
await m_client.WriteAsync(progressReport);
}
public IAsyncEnumerable<ProgressReport> ProgressReports(ChannelName channelName)
{
var call = m_client.Subscribe(channelName);
return call.ResponseStream
.ToAsyncEnumerable()
.Finally(() => call.Dispose());
}
}
写入方法的进展:
while (inProgress)
{
progressServiceClient.Write(new GrpcServer.ProgressReport
{
Id = Task.Id.ToString(),
PercentDone = percentDone,
TimeRemain = timeRemain
}).Wait();
Thread.Sleep(500);
}
进度读取方法:
m_progressService = new ProgressServiceClient();
ChannelName channelName = new ChannelName() { Id = id };
var cts = new CancellationTokenSource();
_ = m_progressService.ProgressReports(channelName)
.ForEachAsync((x) =>
{
Log.Debug($"id: {x.Id} progress: {x.PercentDone}");
}, cts.Token);
this.Dispatcher.Invoke(() =>
{
Application.Current.Exit += (_, __) => cts.Cancel();
this.Unloaded += (_, __) => cts.Cancel();
});
感谢@jdweng为我指出了正确的方向,这个问题通过在主机名后面添加DNS后缀(在我的例子中是skylake.lan)得到了解决。我们可以通过ipinterfaceproperties . DNS suffix获得DNS后缀。
或者,(这可能更安全)我们可以通过使用类似的东西来使用正确的IP地址而不是主机名。
我已经检查了关于同一问题的大多数主题,但我找不到解决方案。 我的应用程序使用连接到一个服务,当我使用托管该服务的机器的IP地址时,它工作正常。但是,当我用主机名替换它时,它无法连接。我使用的连接方法非常标准: 例外情况是: JAVA网。UnknownHostException:无法解析主机“myHostname”:没有与主机名关联的地址 myHostname是我的实际主机名。 当我在我的电脑上使用
我有一个评估csv文件的语法,它根据TestRig正常工作。将生成以下解析树: 但是,如果我在应用程序中使用以下java代码,解析将失败,并出现错误: 更新:我现在直接从文件中使用Char流,但错误仍然存在。 我的理解是,TestRig也会这样做,那么这怎么可能成功,而这怎么可能失败呢? 下面是测试。我用来测试的csv: 至于我如何调用TestRig,我使用命令行: 更新:使用时 我也有同样的错误
问题内容: 我想知道是否有一种方法可以用Java获取计算机名称?我已经看到了该功能的几个答案。但是我想知道是否存在不使用网络的方法? (作为一个附带的问题,计算机名称是否仍然只是一个网络事物,因此必须以这种方式进行??) 问题答案: 操作系统的基础DNS(域名系统)库从IP地址 解析 计算机“名称”。跨操作系统没有通用的计算机名称概念,但DNS通常可用。如果尚未配置计算机名称,以便DNS可以解析它
我建立了一个tic_tac_toe(板)游戏对AI电脑播放器在java,我写了一个MiniMax算法的电脑 下面是我写的MiniMax算法: eval函数是用来计算网格的,我只是把它做成一个例子,下面是函数: 有人知道为什么会这样吗? 函数将获取此棋盘,并通过查找棋盘中的第一个空字符并放置“X”或“O”来尝试查找此棋盘的所有可能移动,这取决于玩家的回合,并返回新棋盘的列表,代码如下。
我有一个gRPC客户端调用同一台机器上的服务器,并且客户端代码使用使用以下创建的通道: 这很有效,我得到了预期的回复。 但是,如果我将“localhost”替换为实际的机器名称(FQDN)或IP地址,我会收到一个错误: 我还测试了在远程机器上启动服务器,并在创建通道时让客户端调用该远程机器(通过名称或IP),但遇到了同样的失败。该应用程序是用C#编写的。NET Core 3.2作为控制台应用程序。