Возможно ли иметь несколько типов служб и конечных точек служб в одном ServiceHost? - PullRequest
0 голосов
/ 06 сентября 2018

Работа с .NET 3.5, но также приветствуются решения 4.5.

У меня есть несколько WSDL, каждый из которых определяет один уникальный веб-сервис, который мне нужно разместить в качестве сервера. Следующий код иллюстрирует, как я запускаю один веб-сервис :

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Playground
{
    class Program
    {
        static BasicHttpBinding GetBinding()
        {
            var binding = new BasicHttpBinding();
            binding.MaxBufferSize = int.MaxValue;
            binding.MaxReceivedMessageSize = int.MaxValue;
            binding.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
            binding.AllowCookies = true;
            binding.MaxReceivedMessageSize = int.MaxValue;

            return binding;
        }

        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(
                typeof(ServiceAImplementation),
                new Uri("http://127.0.0.1:8081/")
                ))
            {
                host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
                host.Description.Behaviors.Add(
                    new ServiceDebugBehavior
                    {
                        IncludeExceptionDetailInFaults = true
                    });
                host.AddServiceEndpoint(typeof(ServiceAInterface), GetBinding(), "ServiceA.soap");

                try
                {
                    host.Open();
                }
                catch (TimeoutException timeoutExp)
                {
                    Console.WriteLine("Timeout");
                }
                catch (CommunicationException commExp)
                {
                    Console.WriteLine("Communication problem");
                }
                finally
                {
                    Console.WriteLine("Press any key to exit...");
                    Console.ReadLine();
                    host.Close();
                }
            }
        }
    }
}

Я собираюсь добавить несколько типов услуг и точек обслуживания на один хост.

Допустим, у меня есть следующие услуги:

  • ServiceA с ServiceAInterface и ServiceAImplementation, доступно на http://127.0.0.1:8080/ServiceA.soap
  • ServiceB с ServiceBInterface и ServiceBImplementation, доступно на http://127.0.0.1:8081/ServiceB.soap
  • ServiceC с ServiceCInterface и ServiceCImplementation, доступно на http://127.0.0.1:8082/ServiceC.soap

До сих пор я не смог найти способ заставить ServiceHost (обратите внимание на a , что означает один!) Обрабатывать несколько веб-сервисов. В одиночку конструктор (ServiceHost(object, Uri[]) и ServiceHost(type, Uri[]) четко указывают на один хост, одну политику службы. Конечно, можно назначить несколько конечных точек службы, но это не решает проблему, с которой я сталкиваюсь.

Есть ли способ сделать это, или я должен реализовать свой собственный ServiceHost, который делает это?

ОБНОВЛЕНИЕ: Кажется, мой вопрос несколько неясен. Я знаю, что могу создать только некоторые другие хосты, а затем скопировать и вставить код сверху для каждого сервиса (я даже создал версию, в которой каждый хост работает в отдельном потоке). Я ищу решение один хост, несколько сервисов . Я уже провел исследование по предоставлению нескольких сервисных контрактов (интерфейс веб-сервиса) путем добавления отдельных конечных точек сервиса вместе с передачей одной реализации (Service...Implementation из примера кода выше). Проблема заключается в том, что все операции имеют хотя бы одну перекрывающуюся операцию , означающую одну и ту же сигнатуру операции (тип возвращаемого значения, имя и входные параметры), но в зависимости от веб-службы возвращаемое значение может быть другим. Хотя да, imho эти сервисы плохо спроектированы, мне приходится иметь дело с этим.

1 Ответ

0 голосов
/ 06 сентября 2018

Ах, прочитайте ваш запрос неправильно раньше.

Если я теперь вас правильно понимаю, думаю, это то, что вы имеете в виду:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost hostA = new ServiceHost(typeof(ServiceAImplementation), new Uri("http://127.0.0.1:6600/"));
            ServiceHost hostB = new ServiceHost(typeof(ServiceBImplementation), new Uri("http://127.0.0.1:6601/"));

            InitHost<ServiceAInterface>(hostA, "ServiceA.soap");
            InitHost<ServiceBInterface>(hostB, "ServiceB.soap");

            try
            {
                hostA.Open();
                hostB.Open();
            }
            catch (TimeoutException ex)
            {
                Console.WriteLine("Timeout");
            }
            catch (CommunicationException ex)
            {
                Console.WriteLine("Communication problem");
            }
            finally
            {
                Console.WriteLine("Press any key to exit...");
                Console.ReadLine();
                hostA.Close();
                hostB.Close();
            }
        }

        private static BasicHttpBinding GetBinding()
        {
            var binding = new BasicHttpBinding();
            binding.MaxBufferSize = int.MaxValue;
            binding.MaxReceivedMessageSize = int.MaxValue;
            binding.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
            binding.AllowCookies = true;
            binding.MaxReceivedMessageSize = int.MaxValue;

            return binding;
        }

        private static void InitHost<T>(ServiceHost host, string endpointEnd)
        {
            host.Description.Behaviors.Remove(typeof(ServiceDebugBehavior));
            host.Description.Behaviors.Add(
                new ServiceDebugBehavior
                {
                    IncludeExceptionDetailInFaults = true
                });
            host.AddServiceEndpoint(typeof(T), GetBinding(), endpointEnd);

            ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
                smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);
            host.AddServiceEndpoint(
              ServiceMetadataBehavior.MexContractName,
              MetadataExchangeBindings.CreateMexHttpBinding(),
              "mex"
            );
        }
    }
}

screenshot of WCFClient (sorry might be blocked by my firewall)

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