我有一个 Windows 服务,它在同一台机器上生成一个子进程。他们通过 TCP 远程处理两种方式进行通信。子进程 ping 父进程没有问题,但是从父进程的客户端到子进程的远程服务的 ping 调用永远不会返回。
日志显示子进程使用预期的端口和服务名称注册服务器 channel 。但是,我提供 127.0.0.1 作为主机,但是当查看 ChannelData 中的 uri 值时,我看到机器的实际 ip 地址而不是环回地址。使用此实际 IP 地址而不是 127.0.0.1 注册 child 的服务器 channel 没有任何区别。
Netstat 表示预期的端口正在监听:
TCP 0.0.0.0:23167 pc-name:0 LISTENING hostingProcId
TCP 0.0.0.0:23461 pc-name:0 LISTENING hostedProcId
该服务是 WellKnownObjectMode.Singleton。我不知道以下信息是否重要,但以防万一,我没有覆盖可编码对象的 InitializeLifetimeService。
将 secure=false 添加到 cahnnel 属性并没有起到作用,也没有在相关端口上明确设置进出防火墙规则。
我同步跨进程以确保客户端在子进程完全设置之前不会尝试激活远程对象。
有什么想法吗?
父级的客户端设置:
protected RemotingTcpClient(IpcUniplexConfig config)
{
Host = config.Host;
Port = config.Port;
ServiceName = config.ServiceName;
var props = new Hashtable();
props["name"] = ServiceName;
props["timeout"] = config.Timeout;
Channel = new TcpClientChannel(props, null);
ChannelServices.RegisterChannel(Channel, true);
var uri = string.Format("tcp://{0}:{1}/{2}", Host, Port, ServiceName);
Service = (TService)Activator.GetObject(typeof(TService), uri);
}
父级的客户端:
public IpcCallResponseData PingHostedProcess(int processId)
{
return Service.Ping(new IpcCallRequestData(processId));
}
子服务器设置:
protected RemotingTcpServer(IpcUniplexConfig config, TService service, WellKnownObjectMode objectMode)
{
Port = config.Port;
Service = service;
var props = new Hashtable();
props["port"] = Port;
props["name"] = service.ServiceName;
Channel = new TcpServerChannel(props, null);
ChannelServices.RegisterChannel(Channel, true);
RemotingConfiguration.RegisterWellKnownServiceType(Service.GetType(), Service.ServiceName, objectMode);
}
为 child 服务:
public IpcCallResponseData Ping(IpcCallRequestData data)
{
... some processing ...
return new IpcCallResponseData(_processId);
}
最佳答案
如果您想要双向通信,那么您的客户端和服务器都需要注册客户端和服务器 channel 。
希望如果您在 RemotingTcpServer
中创建并注册一个 TcpClientChannel
,然后在 RemotingTcpClient
中创建并注册一个 TcpServerChannel
监听它可能工作的同一个端口!
关于c# - 远程调用永不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22225934/