Тайм-аут Исключение при звонке с wpf-клиента на сервер в одном решении - PullRequest
1 голос
/ 01 ноября 2019

В чем проблема: System.TimeoutException: 'Время ожидания канала запроса при ожидании ответа после 00: 00: 59.977913. Итак, в основном это может быть что угодно.

Что у меня есть:

Я создаю простое решение, чтобы найти исправление. Что меня действительно смущает, так это то, что консольное приложение работает просто отлично, однако wpf-приложение с такой же конфигурацией не работает. Решение включает в себя четыре проекта (код сделан для отладки, пожалуйста, не судите его):

  1. библиотека с контрактами и их реализация.

    public class DeviceService : IDeviceService
    {
      public string GetDevices()
      {
        return "hello world";
      }
    } 
    
    [ServiceContract]
    public interface IDeviceService
    {
        [OperationContract]
        string GetDevices();
    }
    
  2. библиотека с хостом.

    public class DeviceServiceHostFactory
    {
    
      ServiceHost host;
    
      public DeviceServiceHostFactory()
      {
        ServiceMetadataBehavior metadataBehavior;
    
        BasicHttpBinding binding = new BasicHttpBinding();
    
        Uri address = new Uri("http://localhost:4000/");
        host = new ServiceHost(typeof(DeviceService), address);
        Type contract = typeof(IDeviceService);
        host.AddServiceEndpoint(contract, binding, "");
      }
    
      public void Start()
      {
        host.Open();
      }
    
      public void Stop()
      {
        host.Close();
      }
    }
    
  3. настольное приложение, которое запускает службу и использует ее (не работает)

     public partial class MainWindow : Window
     {
       private DeviceServiceHostFactory _deviceService;
    
       public MainWindow()
       {
         InitializeComponent();
    
         try
         {
            _deviceService = new DeviceServiceHostFactory();
            _deviceService.Start();
         }
        catch (Exception ex)
        {
            _deviceService.Stop();
            Console.WriteLine(ex.StackTrace);
        }
      }
    
      private void Btn_custom_Click(object sender, RoutedEventArgs e)
      {
        BasicHttpBinding binding = new BasicHttpBinding();
        EndpointAddress endpoint =
            new EndpointAddress("http://localhost:4000/");
    
        var factory =
            new ChannelFactory<IDeviceService>(
                binding, endpoint);
    
        var channel = factory.CreateChannel();
        txt_custom.Text = channel.GetDevices();
    
        Console.WriteLine();
      }
    } 
    
     [ServiceContract]
     public interface IDeviceService
     {
       [OperationContract]
       string GetDevices();
     }
    
  4. консольное приложение (работает нормально)

    class Program
    {
    
      static void Main(string[] args)
      {
        DeviceServiceHostFactory _deviceService = new 
             DeviceServiceHostFactory();
    
       try
       {
            _deviceService.Start();
    
            BasicHttpBinding binding = new BasicHttpBinding();
            EndpointAddress endpoint =
                new EndpointAddress("http://localhost:4000/");
    
            var factory =
                new ChannelFactory<IDeviceService>(
                    binding, endpoint);
    
            var channel = factory.CreateChannel();
            Console.WriteLine(channel.GetDevices());
            Console.ReadLine();
        }
        catch (Exception ex)
        {
            _deviceService.Stop();
            Console.WriteLine(ex.StackTrace);
        }
      }
    }
    
    [ServiceContract]
    public interface IDeviceService
    {
      [OperationContract]
      string GetDevices();
    }
    

Я действительно трачу на это много времени, и буду очень благодарен за каждое решение или за мысль, как я могу отладить его более продвинуто.

1 Ответ

0 голосов
/ 06 ноября 2019

Во-первых, мы должны предоставить разрешения текущей учетной записи, когда мы занимаем порты операционной системы для размещения служб.
Эту функцию можно выполнить с помощью следующей команды.

Netsh http add urlacl url= https://+:80/MyUri user = DOMAIN \ user

https://docs.microsoft.com/en-us/windows/win32/http/add-urlacl
Если мы не хотим этого делать, мы можем напрямую запустить службу с учетными записями администратора. Таким образом, я подозреваю, что что-то не так с процессом размещения сервиса. Вы пытались запустить приложение WPF с учетной записью администратора?
Кроме того, я предлагаю вам добавить пространство имен в контракт на обслуживание.

[ServiceContract(Namespace ="MyNamespace")]
public interface IDeviceService
{
    [OperationContract]
    string GetDevices();
}

Иногда оно может столкнуться с проблемами, когда контракт на обслуживание не 'у него есть свойство пространства имен.
Не стесняйтесь сообщить мне, если проблема все еще существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...