使用网络中托管的 WCF 服务抛出 TimeoutException

TimeoutException thrown consuming WCF Service hosted in the Network

我正在编写一个 Web 应用程序,它将在 Raspberry PI 上的 Electron 中托管。 Raspberry PI 附有一个指纹扫描仪,returns 我需要一个字符串来检查指纹是否已在另一台服务器上的数据库中注册。我通过调用托管在网络上的 WCF 服务方法来执行此操作。
现在的问题是调用 WCF 服务时,我在 1 分钟后超时(默认超时),但是当我 运行 本地计算机上的应用程序时它有效。

服务代码:

[ServiceContract(Namespace = "http://192.168.0.154:8733/GlauxSoft.SnackBox.WebService/")]
public interface IService
{
        [OperationContract]
        Fingerprint GetFingerprintByUniqueId(string uniqueId);
}

public class Service : IService
{
    public Fingerprint GetFingerprintByUniqueId(string uniqueId)
    {
        // This is just a DataBase call, nothing extraordinarily expensive
        using (EvidenceSessionHelper.CreateDefaultWebServiceSession())
        {
            return Fingerprint.MapAuthentifizierungToWebServiceFingerprint(QueryAuthentifizierung.GetFingerprintByUniqueId(uniqueId));
        }
    }
}

消费者代码:

[ServiceContract(Namespace = "http://192.168.0.154:8733/GlauxSoft.SnackBox.WebService/", ConfigurationName = "ISnackBoxService")]
public interface ISnackBoxService
{
    [OperationContract(
        Action ="http://192.168.0.154:8733/GlauxSoft.SnackBox.WebService/IService/GetFingerprintByUniqueId", 
        ReplyAction = "http://192.168.0.154:8733/GlauxSoft.SnackBox.WebService/IService/GetFingerprintByUniqueIdResponse")]
    Fingerprint GetFingerprintByUniqueId(string uniqueId);
}

public class ServiceClient : ClientBase<IService>, IService
{
    public SnackBoxServiceClient() : 
            base(GetDefaultBinding(), GetDefaultEndpointAddress())
    {
        Endpoint.Name = EndpointConfiguration.BasicHttpBinding_ISnackBoxService.ToString();
    }

    public enum EndpointConfiguration
    {
        BasicHttpBinding_ISnackBoxService
    }

    public Fingerprint GetFingerprintByUniqueId(string uniqueId)
    {
        return Channel.GetFingerprintByUniqueId(uniqueId);
    }
}

消费者是一个 ASP.NET 用 .NET Core 3 Preview 5 编写的 Razor 应用

我这样调用消费者代码:

var service = new ServiceClient();
var evdFingerprint = service.GetFingerprintByUniqueId("Test String"); // <-- Runs for 1 minute and throws the TimeoutException

这是堆栈跟踪:

System.TimeoutException: The request channel timed out attempting to send after 00:01:00. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://192.168.0.154:8733/GlauxSoft.SnackBox.WebService/' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. at System.ServiceModel.Channels.HttpChannelFactory`1.HttpClientRequestChannel.HttpClientChannelAsyncRequest.SendRequestAsync(Message message, TimeoutHelper timeoutHelper) at System.ServiceModel.Channels.RequestChannel.RequestAsync(Message message, TimeSpan timeout)

编辑: 我做了一些进一步的测试,似乎对我的本地机器的任何 HTTP 请求都没有像 wget 192.168.0.154:5106 -o index.html 和监控我的一样通过使用 wireshark 的网络流量没有向我显示对我的电脑的任何 GET 请求,并且 https://192.168.0.154:5106 也会超时。
但是,我可以 ping 我的本地电脑,甚至可以通过 SSH 连接到我的 Raspberry PI,我还可以与我的 Raspberry PI

建立 VNC 远程桌面会话

您可以通过多种方式在绑定上配置超时。在代码中,

    WSHttpBinding binding = new WSHttpBinding();
    binding.OpenTimeout = new TimeSpan(0, 10, 0);
    binding.CloseTimeout = new TimeSpan(0, 10, 0);
    binding.SendTimeout = new TimeSpan(0, 10, 0);
    binding.ReceiveTimeout = new TimeSpan(0, 10, 0);

或在web.config

<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding openTimeout="00:10:00" 
                 closeTimeout="00:10:00" 
                 sendTimeout="00:10:00" 
                 receiveTimeout="00:10:00">
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

GetDefaultBinding(), GetDefaultEndpointAddress()

我希望你能与我分享更多与上述方法体相关的细节。
默认绑定的 ClientCredentailType 是什么?因为某些绑定与核心(WS-* 绑定)不太兼容。另外,你在其他机器上调用服务时,是否在客户端修改了服务端点地址?
在我看来,我们可以使用 Microsoft WCF Web Service Reference Provider 工具生成客户端代理,然后根据服务器端的绑定配置修改服务端点地址并显式提供客户端凭据。
如果问题仍然存在,请随时告诉我。

修复很简单,我需要使用 HTTPS,所以没有连接到 http://192.168.0.154:8733/... 我需要连接到 https://192.168.0.154:8733/...