WCF: получение доступа к форме (способ 2)
Всем доброго времени суток. На связи Алексей Гулынин. В данной небольшой статье я бы хотел рассказать ещё про один способ получения сервисом доступа к форме.
Будем использовать следующий механизм: создадим вспомогательный класс, в котором будем получать ссылку на текущую форму. Также создадим метод, который будет в текстовое поле записывать отправляемые сообщения. В примере наша форма уже не будет являться сервисом.
Сразу приведу код измененной серверной части:
using System; using System.Linq; using System.Windows.Forms; using System.ServiceModel; namespace Server { public partial class FormServer : Form { ServiceHost serviceHost; public FormServer() { InitializeComponent(); } private void btn_Start_Click(object sender, EventArgs e) { try { if (serviceHost == null) { // Создание экземпляра ServiceHost // Здесь мы теперь передаём Service, а не this, // как было в предыдущем примере serviceHost = new ServiceHost(typeof(Service)); serviceHost.Open(); tB_Server_Info.Text += "Сервер запущен." + Environment.NewLine; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void btn_Stop_Click(object sender, EventArgs e) { try { if (serviceHost != null) { serviceHost.Close(); serviceHost = null; tB_Server_Info.Text += "Сервер остановлен." + Environment.NewLine; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } // Наш сервис, который реализует контракт class Service : IContract { public string Print(string str) { MyForm.UpdateText("От клиента пришло сообщение: " + str + Environment.NewLine); return "Сообщение клиента: " + str; } } // Внутренний вспомогательный класс internal static class MyForm { // Получаем ссылку на текущую форму static readonly FormServer form1 = Application.OpenForms.Cast<FormServer>().First(); // Данный метод обновляет информацию в текстовом поле public static void UpdateText(string str) { form1.tB_Server_Info.Text += str; } } }
Модификатор доступа у свойства tB_Server_Info необходимо изменить с private на public, чтобы иметь возможность изменять это свойство вне класса FormServer. Изменить его можно в коде дизайнера.
Также необходимо в файле App.config изменить service name ="Server.Form1" на service name ="Server.Service".
В классе MyForm мы получаем ссылку на текущую форму.
Ниже под хайдом приведу весь остальной код.
Не забываем файл IContract.cs добавлять в оба проекта:
[ServiceContract] interface IContract { [OperationContract] string Print(string str); }
App.config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name ="Server.Service"> <host> <baseAddresses> <add baseAddress="http://localhost:343/IContract"/> </baseAddresses> </host> <!-- указываем адрес, привязку и контракт --> <endpoint address="" binding="basicHttpBinding" contract="Server.IContract" /> </service> </services> </system.serviceModel> </configuration>
Клиентский код:
using System; using System.ServiceModel; using System.Windows.Forms; namespace Client { public partial class FormClient : Form { // Адрес Uri address = new Uri("http://localhost:343/IContract"); // Привязка BasicHttpBinding binding = new BasicHttpBinding(); // Фабрика каналов, один из которых будет реализовать контракт ChannelFactory<IContract> factory; // Ссылка на канал. IContract channel; public FormClient() { InitializeComponent(); } private void btn_Send_Click(object sender, EventArgs e) { try { if (factory == null) { factory = new ChannelFactory<IContract>(binding, new EndpointAddress(address)); // Создаём канал channel = factory.CreateChannel(); } if (factory != null && channel != null) { tB_Client_Info.Text += "Моё сообщение: " + tB_Client_Send.Text + Environment.NewLine; // Здесь уже сервер отправляет сообщение клиенту tB_Client_Info.Text += "Сообщение с сервера: " + channel.Print(tB_Client_Send.Text) + Environment.NewLine; // Обнуляем поле с текстом для отправки сообщения tB_Client_Send.Text = ""; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } } }
В данной статье вы узнали ещё один способ получения сервисом доступа к форме в .NET Framework.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.