Создание собственной службы WCF внутри формы Windows - PullRequest
0 голосов
/ 27 сентября 2018

Если я использую этот код для самостоятельного размещения службы WCF в консольном приложении, она работает.Я запускаю приложение хоста, а затем из другого приложения (которое я называю клиентским приложением) я могу добавить ссылку на службу из Visual Studio> Обозреватель решений> ДОБАВИТЬ СЕРВИСНАЯ ССЫЛКА> http://10.131.131.14:8080/sendKioskMessage> нажмите GO, добавьте службу сбез проблем и потребляет его из клиентского приложения (которое является формой Windows)

Но если я запускаю тот же код в форме Windows, я запускаю сначала приложение формы Windows (SELF HOST WCF), а затем издругое приложение (клиентское приложение) в Visual Studio. Я пытаюсь добавить ссылку на службу из ADD SERVICE REFERENCE в обозревателе решений (точно так же, как это работает раньше, но с собственным хостом Console App), но выдает следующую ошибку:

*

Произошла ошибка (Подробности) при попытке найти службы по адресу http://10.131.131.14:8080/sendKioskMessage.

(Если я нажму ссылку Подробности, появится следующее сообщение:)

Произошла ошибка при загрузке 'http://10.131.131.14:8080/sendKioskMessage/$metadata'. Невозможно подключиться к удаленному серверу.Метаданные содержат ссылку, которая не может быть разрешена: 'http://10.131.131.14:8080/sendKioskMessage'. Не было прослушивающей конечной точки на http://10.131.131.14:8080/sendKioskMessage, которая могла бы принять сообщение.Это часто вызвано неправильным адресом или действием SOAP.Смотрите InnerException, если имеется, для более подробной информации.Невозможно подключиться к удаленному серверу.Если служба определена в текущем решении, попробуйте создать решение и снова добавить ссылку на службу.

*

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

Код формы Windows (не удается добавить службу из другого приложения):

public partial class KioskosServerForm : Form
    {


        [ServiceContract]
        public interface IKioskMessageService
        {
            [OperationContract]
            string SendKioskMessage(string message);
        }

        public class KioskMessageService : IKioskMessageService
        {
            public string SendKioskMessage(string message)
            {
                return string.Format("Message sent: {0}", message);
            }
        }

        public KioskosServerForm()
        {
            InitializeComponent();
        }

        private void KioskosServerForm_Load(object sender, EventArgs e)
        {
            Uri baseAddress = new Uri("http://10.131.131.14:8080/sendKioskMessage");

            try
            {
                // Create the ServiceHost.
                using (ServiceHost host = new ServiceHost(typeof(KioskMessageService), baseAddress))
                {
                    // Enable metadata publishing.
                    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                    smb.HttpGetEnabled = true;
                    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                    host.Description.Behaviors.Add(smb);

                    // Open the ServiceHost to start listening for messages. Since
                    // no endpoints are explicitly configured, the runtime will create
                    // one endpoint per base address for each service contract implemented
                    // by the service.
                    host.Open();
                }
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.InnerException.Message);
            }
        }
    }

Код консольного приложения (работает!Я могу добавить службу из другого клиентского приложения):

[ServiceContract]
public interface IKioskMessageService
{
    [OperationContract]
    string SendKioskMessage(string message);
}

public class KioskMessageService : IKioskMessageService
{
    public string SendKioskMessage(string message)
    {
        return string.Format("Message sent: {0}", message);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Uri baseAddress = new Uri("http://localhost:8080/sendKioskMessage");

        // Create the ServiceHost.
        using (ServiceHost host = new ServiceHost(typeof(KioskMessageService),baseAddress))
        {
            // Enable metadata publishing.
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            // Open the ServiceHost to start listening for messages. Since
            // no endpoints are explicitly configured, the runtime will create
            // one endpoint per base address for each service contract implemented
            // by the service.
            host.Open();

            Console.WriteLine("The service is ready at {0}", baseAddress);
            Console.WriteLine("Press <Enter> to stop the service.");
            Console.ReadLine();

            // Close the ServiceHost.
            host.Close();
        }
    }
}

Я не знаю, почему я могу использовать службу, если служба размещена в консольном приложении, но я не могу добавить ее, еслиСлужба размещается в форме Windows.

Я буду очень признателен за помощь в достижении этого с помощью Windows From, поскольку мне нужно самостоятельно размещать службу WCF из формы Windows, а не консольное приложение.

Я использую Visual Studio 2017, .Net Framework 4.6.1

СПАСИБО В ADVANCE GUYS !! !! 1040 *

1 Ответ

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

TL; DR консольное приложение работает, потому что у вас есть задержка перед закрытием службы;хост WinForms не


Причина, по которой ваша консольная служба хоста WCF работает, заключается в том, что вы запускаете хостинг и продолжаете до строки Console.ReadLine():

host.Open();

Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();  // <-------- program waits here

// Close the ServiceHost.
host.Close();

...после чего сервис срывается.До этого другие клиенты могут нормально подключаться и добавить сервисные ссылки .

Приложение WinForms имеет нет такая задержка:

private void KioskosServerForm_Load(object sender, EventArgs e)
{
    Uri baseAddress = new Uri("http://10.131.131.14:8080/sendKioskMessage");

    try
    {
        // Create the ServiceHost.
        using (ServiceHost host = new ServiceHost(typeof(KioskMessageService), baseAddress))
        {
            // Enable metadata publishing.
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
                host.Description.Behaviors.Add(smb);

            // Open the ServiceHost to start listening for messages. Since
            // no endpoints are explicitly configured, the runtime will create
            // one endpoint per base address for each service contract implemented
            // by the service.
            host.Open();  // <------ opened here
        } // <------ shutdown here
     } 
     catch (Exception exp)
     {
         MessageBox.Show(exp.InnerException.Message);
     }
}

... он немедленно отключается, когда код выходит из области действия блока using.using автоматически вызовет Dispose() для объекта host, который, в свою очередь, вызывает Close().

Подумайте о размещении хоста в переменную следующим образом:

ServiceHost _host;  // <---------- new!

private void KioskosServerForm_Load(object sender, EventArgs e)
{
    Uri baseAddress = new Uri("http://10.131.131.14:8080/sendKioskMessage");

    try
    {
        // Create the ServiceHost.
        _host = new ServiceHost(typeof(KioskMessageService), baseAddress))
        // Enable metadata publishing.
        ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
        smb.HttpGetEnabled = true;
        smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
       _host.Description.Behaviors.Add(smb);

        // Open the ServiceHost to start listening for messages. Since
        // no endpoints are explicitly configured, the runtime will create
        // one endpoint per base address for each service contract implemented
        // by the service.
        _host.Open();
     }
     catch (Exception exp)
     {
         MessageBox.Show(exp.InnerException.Message);
     }
 }

Позже вы можете закрыть экземпляр _host с помощью вызова Close.

...